min_25 筛与洲阁筛
1. \(F_k\) 函数
现在假设要求积性函数 \(f(x)\) 的前缀和,我们设 \(minp(x)\) 函数代表 \(x\) 的最小质因子是第几个质数,设 \(F_k(x)\) 函数表示在 \([2,x]\) 中 \(minp(i)\geq k\) 的 \(f(i)\) 的和。
这样,我们需要求的前缀和即为 \(F_1(n)+1\) 。考虑递归求解 \(F_k(x)\) 函数。
对于 \(F_k(x)\) ,只考虑 \(F_k(x)\) 所求的范围中的数。将最小因子 \(p_i\) 的影响全部去掉,枚举 \(p_i\) 对应的次数 \(c\) ,则 \([1,x]\) 当中所有 \(minp(x)=p^i\) 且唯一分解中 \(p_k\) 的次数恰好等于 \(c\) 的数的贡献都可以分离出一个 \(f(p_k^c)\) 。对于还有因数的数,接着递归求解。则有
这样复杂度比 \(O(n)\) 还要差。发现当 \(p_i^c\leq x<p_i^{c+1}\) 的时候,考虑贡献的数中不存在仍含有比 \(p_i\) 大的因数,不递归。
里面 \(F_p(x)\) 就是 \([1,x]\) 中质数的函数值的和。
然后你直接递归去做这个做法,它就和杜教筛类似,只在 \(x\) 为整除分块点的时候才会被遍历,看起来就很快了。
但这个做法有十分精密的复杂度证明:我们发现真的递归去求函数,每次 \(f(p_i^c)\) 事实上是求一个最大质因子是 \(p_i^c\) 的数的答案,这部分仍然是一个一个求的。所以这个做法事实上优化掉的是被质数前缀和 \(F_p(x)=F_p(p_{k-1})\) 求出的答案,也就是那些最大质因子是 \(p_i\) 仅有一次的数。
仔细思考,由于我们排除掉了 \(p_i^2>x\) 以至于不需要递归的 \(i\) 的枚举,事实上复杂度瓶颈就是求 \(f(p_i^c)\),也就是说复杂度是“最大质因数不是二次的数的个数”。
经过估算,这个复杂度在 \(O(\frac{n^\frac{3}{4}}{\log n})\),实际应用和杜教筛差不多快,\(10^{12}\) 可以跑。
不过需要预处理一个 \(F_p(x)\)。
2.\(F_p\) 函数
这个时候 \(f(p)\) 通常形式简单,如 \(\varphi(p)=p-1\),我们不妨设 \(f'(x)=x-1\),并求 \(f'(x)\) 在所有质数点值的和。
于是设 \(F_p(x)\) 表示 \(\sum_{i=1}^{p_i\leq x} f'(p_i)\),仍然按埃氏筛的想法考虑。
设 \(G_k(x)=\sum_{i=1}^x f'(i) [i\in P||minp(i)>p_k]\) ,即为埃氏筛进行到 \(p_k\) 之后剩下的数,包括最大质因数大于 \(p_k\) 的数以及质数。则 \(F_p(x)=G_{|P|}(x)\) ,其中 \(P\) 为筛到 \(\sqrt n\) 的素数,因为埃氏筛只筛到 \(\sqrt n\) 即可。这样 \(G_0(x)=\sum_{i=1}^n f'(i)\) 是易于用求和公式计算的。
每次筛相当于把所有以 \(p_k\) 为最小质因数的数删掉,由于 \(f'(x)\) 也是积性函数,所以 \(-f'(p_k)G_{k-1}(n/p_k)\) ,因为 \(G_{k-1}\) 里最小值因数一定大于等于 \(p_k\),但是别忘了 \(G_{k-1}\) 里面还有小质数,于是再 \(+p_k^tG_{k-1}(p_{k-1})\) 把这些去掉。得到递推式
3.代码实现
具体实现的时候做 \(F_k(x)\) 函数不需要所有的 \(F_p(x)\) 。分别考虑递归式里的两种情况。
首先是递推公式里用到的 \(F_p(p_{k-1})\)、\(G_{k-1}(p_{k-1})\) 这些特殊点值,因为埃氏筛过程肯定不会用到 \(\sqrt n\) 以上的质数,所以这些点值就是 \(\sqrt n\) 以下的质数点值的前缀和。这个可以线性筛预处理。
然后 \(F_p(x)\) 会访问的点一定是 \(n\) 的整除分块点,更进一步,我们只算这些的话 \(G_k(x)\) 也只需要这些点。所以我们可以用一个数组把 \(G\) 存下来,从小到大枚举 \(k\) 来更新 \(G\)。这样每个整除分块点 \(i=\left\lfloor\frac{n}{l......r}\right\rfloor\),只有在 \(p_k^2\le i\) 的时候会被访问,这个复杂度也是 \(O(\frac{n^\frac{3}{4}}{\log n})\) 的,神奇地实现了复杂度平衡。
至于怎么用数组存下所有整除分块点 \(i\),可以分 \(i<\sqrt n\) 的和 \(\left\lfloor\frac{n}{i}\right\rfloor<sqrt n\) 的两种,分别存在一个根号以下的下标。
然后只需要 \(O(\sqrt n)\) 的空间复杂度即可。
另一个要点是递归的时候,由于这部分复杂度分析其实不依赖 \((p,x)\) 对出现次数,所以完全没必要像杜教筛一样开 map 避免重复计算。
尽管跑 n=10000000000 递归的时候一个函数值最多会重复求 600 次
4.洲阁筛
杜教筛套整除分块之后复杂度不变,但是min_25筛就不是。毕竟你 map 去重都没加
需要进行整除分块次min_25筛的话,考虑改变 \(F_k(x)\) 的定义
设 \(F_k(x)=\sum_{i=1}^x f(x) [i\in P||minp(i)>=p_k]\) ,和求 \(F_p\) 时类似,表示埃氏筛进行到 \(p_{k-1}\) 之后剩下的数。当 \(p_k^2\leq x\) 时,可以类似求 \(F_p\) 反过来,每次加入在 \(k\) 轮中被筛掉而 \(k-1\) 轮中没有删掉的数。直接给出式子
边界条件为 \(F_{|P|+1}(x)=F_p(x)\) ,即只剩下质数的情况。
这样用和求 \(F_p\) 一样的递推的代码实现就能求出 \(F_k(x)\)。
这次复杂度分析就得用到 \((x,p)\) 对出现的次数了。因为 \(n^{\frac{1}{2}}+n^{\frac{1}{3}}+......\) 其实是 \(\sqrt n\) 级别的,所以这部分复杂度其实和求 \(F_p\) 相同,都是 \(O(\frac{n^\frac{3}{4}}{\log n})\) 的,不过显然常数大了一些。
事实上这个跑 1e11 有点费劲。
5.用法
由于min_25筛会一个一个处理最大质因数大于二次的数这一特点,可以处理最大质因数之类的问题。

浙公网安备 33010602011771号