1 条题解
-
0
题目分析
题目定义了一个函数 ,其性质明确表明它是一个积性函数:
- 在质数幂 处的取值定义为 ( 为质数, 为异或运算)
- 当 与 互质时,
我们的目标是求出这个积性函数 的前缀和,即 ,并对 取模。
数据范围 是一个强烈的信号,表明我们需要使用亚线性时间复杂度的算法。
算法选择
对于积性函数前缀和问题,在 很大时,主要有两种强大的筛法:
- 杜教筛:适用于存在另一个积性函数 ,使得 的前缀和易于计算的情况。
- Min_25筛:适用性更广,要求积性函数 在质数 和质数幂 处的表达式是一个关于 的低次多项式,或者是易于计算的。
分析我们的函数 :
- 在质数点 (即 ) 处,。
- 这个表达式 不是一个关于 的多项式。它依赖于 的二进制表示。
因此,标准的 Min_25 筛模板不能直接应用。我们需要对其进行改造。
改造的 Min_25 筛思路
标准的 Min_25 筛将问题分为两部分:
- 质数部分和:计算所有质数 的 之和。
- 合数部分和:通过枚举最小质因子递归计算。
难点在于第一部分。标准 Min_25 筛使用多项式来拟合质数处的函数值,但 无法用多项式拟合。
解决方案: 我们可以利用 按位处理 (Digit DP) 的思想。注意到 的值只与 的二进制位有关。我们可以将 按二进制位拆分,根据每一位是 0 还是 1 来分类讨论它对 的贡献。
具体地,在 Min_25 筛的第一阶段(“筛质数”阶段),我们不再维护一个单一的多项式函数,而是维护一个状态,该状态记录了在当前处理的数位下,满足条件的质数的某种“贡献和”。
这个过程可以看作是一个数位 DP 与 Min_25 筛的结合。我们定义状态
dp[pos][tight][...]:pos:当前正在处理的二进制位。tight:当前是否受到 的限制。- 其他状态可能需要记录当前已经累积的质数个数、当前累积的 值等。
通过这个 DP,我们可以“数”出所有小于等于 的质数 的 之和。
算法流程
-
预处理:
- 使用线性筛预处理出 以内的所有质数。
- 初始化 Min_25 筛和数位 DP 所需的数据结构。
-
计算质数部分和 :
- 使用结合了数位 DP 思想的 Min_25 筛,计算 。
- 这是整个算法的核心和最复杂的部分。
-
计算合数部分和 :
- 使用标准的 Min_25 筛第二部分流程,递归地枚举合数的最小质因子及其指数。
- 对于一个合数,设其最小质因子为 ,指数为 ,剩余部分为 (与 互质),则 。
- 这里 是已知的, 可以通过递归或查表得到。
-
合并结果:
- 总的前缀和 。
- 最终结果对 取模。
复杂度分析
- 改造后的 Min_25 筛(结合数位 DP)的时间复杂度仍然为 或 ,但其常数会大很多,因为状态转移涉及二进制位操作。
- 空间复杂度为 。
代码实现要点(伪代码)
MOD = 10**9+7 def precompute_primes(sqrt_n): # 线性筛获取 sqrt(n) 内的质数 def digit_dp_min25(n): # 将 n 转换为二进制 bits = bin(n)[2:] L = len(bits) # dp[pos][tight][cnt][sum] 或其他状态定义 dp = initialize_dp_state() dp[0][True][...] = initial_state for pos in range(L): for tight in [True, False]: for ... in state: # 遍历其他状态 if dp[pos][tight][...] is valid: current_bit = int(bits[pos]) if tight else 1 for next_bit in [0, 1]: if next_bit <= current_bit: new_tight = tight and (next_bit == current_bit) # 根据 next_bit 更新状态(例如,对质数个数、f(p)和的贡献) update_dp_state(...) return final_result_from_dp def min25_sieve_part2(n, primes): # 使用递归或迭代计算合数部分的贡献 # G(n, k) 表示从第 k 个质数开始,最小质因子 >= primes[k] 的合数的 f(i) 和 # G(n, k) = sum_{j>=k} sum_{c>=1, e = primes[j]^c <= n} [ f(e) * (1 + G(floor(n/e), j+1)) ] ... def main(n): if n == 0: return 0 primes = precompute_primes(int(n**0.5)+1) S_prime = digit_dp_min25(n) # 计算所有质数p的 f(p)=p XOR 1 的和 S_comp = min25_sieve_part2(n, primes) return (1 + S_prime + S_comp) % MOD总结
本题是一道非常具有挑战性的数论题目,它考察了选手对积性函数、Min_25 筛原理的深刻理解,以及将数位 DP 思想灵活应用于解决非标准形式函数求和问题的能力。其核心创新点在于通过数位 DP 来克服 Min_25 筛对质数点函数形式的限制。
- 1
信息
- ID
- 5064
- 时间
- 1000ms
- 内存
- 256MiB
- 难度
- 10
- 标签
- 递交数
- 1
- 已通过
- 1
- 上传者