Min25筛
毒×2。
一般用来求积性函数 f(x) 的前缀和,此外还可以拓展到部分非积性函数的质数部分。
那么总的来说算法仅分为几个步骤,第一步是求出质数对应的 f(x) 的前缀和,下一步是根据第一步所求的去推演全部 f(x) 的前缀和。
一般的积性函数都不太简单,那么我们需要去构造一个完全积性函数去拟合原函数。当然,我们需要的仅仅是让构造的函数去让在质数处与原函数相同来达到我们的目的,因为我们仅需用它就可以通过积性函数的性质推广到全局。
那么我们用 g(i,j) 来表示在 [2,i] 中去除了前 j 个质数的倍数后剩余数字的 f(x) 和,在这里倍数的定义为严格大于一倍。那么我们需要注意的是 g(i,j) 一直包含且仅包含区间内所有的质数的 f(x) ,我们最终要求的就是 g(n,+∞),即只留下质数。
设质数 px ,求 g 的过程也就是删除每一个 kpx,(k>1) 的贡献的过程。显然 k 不是 px 之前的质数的倍数,因为我们已经用它们删除过贡献了。
设我们构造的函数为 f′(x) ,那么由于其完全积性函数的性质,可得到 f(kpi)=f(k)f(pi)
那么
g(i,j)=g(i,j−1)−f′(pj)⋅[g(⌊pji⌋,j−1)−k=1∑j−1f(pk)],pj<=n
后面的括号中式子含义也就是加回来多减去的质数的贡献,因为 g(⌊pji⌋,j−1) 里包含了质数本身的贡献,但是由于定义可得我们需要加回来,所以要在括号里减去多减的,拿出括号外来也就是加回来了。
为啥有这个根号范围的限制?显然我们在这个范围之外肯定没有更多的因子去筛了,原理同线性筛。
那么如何求 f 的 sum?线性筛即可。
同时,我们需要对 g(i,0) 去赋初值,所以我们设定函数的第二个限制就是要能够方便地求前缀和,所以我们一般会选择一个单项式来构造。
但是 [1,n] 的范围仍然无法承受。发现只需要 g(n,+∞) ,所以这玩意只会递归到 形如 i=⌊vn⌋ 的地方。那么只需要对这样的 i 求解即可。
我们可以预处理出来符合条件的 i ,当 x>n 时放在一个数组里即可,用 ⌊xn⌋ 作为下标。
好,我们已经成功地迈出了第一步,下一步只需要考虑合数的贡献。
显然合数的最小值因子不会大于 n ,那么可以直接枚举它。设 x 最小质因子为 γ(x)
再设
h(i,j)=x=2∑i[γ(x)≥pj]f(x)
所以答案就是 h(n,1)
可得
h(i,j)=g(i,+∞)−k=0∑j−1f(k)+x≥j∑k∑pxk≤if(pxk)⋅[h(⌊pxki⌋,x+1)+[k=1]]
即用 $g(i,+\infty)-\sum\limits_{k=0}^{j-1}f(k) $
来计算在 [2,i] 范围内的质数,用 $f({p_x}^k)\cdot h(…) $ 去计算 至少含有两个质因子的合数,用 $ [k \ne 1]f({p_x}^k) $ 去计算了只含有一个质因子的合数,那么就不重不漏地算完了我们想要的。
当然,在 $ \lfloor \frac{i}{ {p_x}^k}\rfloor<p_k $ 时,h(...) 这一项为0,可以跳过计算。
那么我们递归时就要求 $ \lfloor \frac{i}{ {p_x}^k}\rfloor \ge p_k $ ,而这个范围也是恰好使 $ {p_x}^{k+1} $ 为只含有一个质因子的合数,所以实现并不难 (才有鬼)
同理, px≤i 时才可以进行转移。
无了。
我讲的是递归法,当然还有递推法,先鸽了。