• 「总结」筛法


    转眼就快联赛了,把筛法总结一下吧。

    目前会的只有三个,埃筛,线筛,杜教筛。

    怎么说这个东西。其实非常灵活。

    首先我们知道筛法大多数用来筛积性函数,所以而积性函数和质数关系很大,所以先说一下怎么筛质数吧。

    1.质数筛

    $fr.$根号$n$暴力判断。

    相当与在枚举因数,如果这个数没有非平凡因子($n$除了$1,n$之外的因子),那么这个数是质数。

    复杂度:$O(sqrt{n})$

    $se.$埃筛

    枚举每一个数,用它的倍数来筛掉合数。

    复杂度是:$O(nlnln n)$

    $th.$线筛

    枚举每一个质数,和 合数或质数相乘 筛掉合数,保证是被筛掉的合数的最小质因子,这样每个数被筛掉一次,枚举到一次。

    复杂度是:O(n)

    质数筛就这些了。

    然后筛一些积性函数的单点,一般都用线筛了。

    线筛为了保证复杂度,筛的时候要分三种情况讨论。

    下面举几个例子来说明:

    1.欧拉函数

    $$varphi(n)=sumlimits_{i=1}^{n}[iperp n]$$

    考虑每一个质因子的贡献。

    设$n=\_*p^c$

    对于每个$p^c$来说,对答案的贡献就是$p^cfrac{p-1}{p}$,感性理解一下其实相当与一个类似“互质密度”的东西,也就是说在每一个$p$大小的区间中,互质的数的分布是均匀的。

    欧拉函数是积性函数,那么:

    $$varphi(n)=prod p^cfrac{p-1}{p}=nprodfrac{p-1}{p}$$

    我们来线筛它。

    $fr.iin p$那么$varphi(i)=i-1$

    $se.i%p_j!=0$那么根据积性函数性质,$varphi(ip_j)=varphi(i)varphi(p_j)$

    $th.i%p_j==0$根据公式代入,发现新近的质数只对公式最前面的$n$有贡献,而$prod$后面的部分已经被计算了。

    那么:$varphi(ip_j)=varphi(i)p_j$

    2.约数个数

    设$n=\_*p^c$

    根据定义,枚举每个质因子在约数中的指数得到:

    $d(n)=prod c+1$

    可以发现是积性函数。

    我们来线筛它。

    首先加入一个辅助数组$a(i)$表示$i$最小的质因子在$i$中的指数。

    $fr.iin p$那么$d(i)=2,a(i)=1$

    $se.i%p_j!=0$根据积性函数的性质,$d(ip_j)=d(i)d(p_j),a(ip_j)=1$

    $th.i%p_j==0$根据公式代入,$d(ip_j)=d(i)frac{a(i)+2}{a(i)+1},a(ip_j)=a(i)+1$

    3.自然数幂函数

    $$f_d(i)=i^d$$

    这是完全积性函数。

    其实要简单很多了就。

    还是套用线筛的模板,然后每乘入一个质数的时候。

    $$f_d(ip_j)=f_d(i)p_j^d$$

    每次筛出质数的时候用快速幂求出$p_j^d$,复杂度是$O(nfrac{log_2(n)}{ln(n)})$的,仍然是线性。

    4.莫比乌斯函数

    $$mu(n)=egin{cases} (-1)^w & n=prodlimits_{i=1}^{w}p_i&\0 & n=p^2prodlimits_{i=1}^{w}p_i^{c_i}&end{cases}$$

    它是积性函数

    我们来线筛它。

    $fr.iin p$那么$mu(i)=-1$

    $se.i%p_j!=0$那么$mu(ip_j)=mu(i)mu(p_j)$

    $th.i%p_j==0$那么$mu(ip_j)=0$

    5.约数和函数

    根据定义,枚举每个质因子在约数中出现的指数。

    设$n=\_*p^c$

    $$sigma(n)=prodsumlimits_{i=0}^{c}p^i$$

    发现是等比数列可以直接求和。

    $$sigma(n)=prodfrac{1-p^c}{1-p}$$

    那么我们需要维护一个函数$b(n)$代表$n$最小的质因子的最大指数次幂,也就是说对于$n$的最小质因子$p$,$b(n)=sumlimits_{i=0}^{c}p^i$,同时需要借用上面筛过的函数$f_d(n)$和$a(n)$。

    我们来线筛它。

    $fr.iin p$那么$b(i)=i+1,sigma(i)=i+1$

    $se.i%p_j!=0$那么$b(ip_j)=p_j+1,sigma(ip_j)=sigma(i)sigma(p_j)$

    $th.i%p_j==0$那么$b(ip_j)=b(i)+f_{a(ip_j)}{p_j},sigma(ip_j)=sigma(i)frac{b(i)}{b(ip_j)}$

    6.最大共因数

    也就是在$k$一定的情况下求:

    $gcd(n,k)=prodlimits_{p}p^{min(c_n,c_k)}$

    可以发现是积性函数。

    仍然利用函数$a(n)$,设函数$g_n(p)$为$n$中质因子$p$的最大幂指数。

    我们来线筛它。

    $fr.iin p$那么$gcd(i,k)=i[i|n]+[iperp n]$

    $se.i%p_j!=0$那么$gcd(ip_j,k)=gcd(i,k)gcd(p_j,k)$

    $th.i%p_j==0$那么$gcd(ip_j,k)=gcd(i,k)(p_j[a(i)<g_n(p_j)]+[a(i)>g_n(p_j)])$

    线筛复杂度已经很优秀了,可是就是有毒瘤出题人出数据出到$1e12$,这时候杜教筛就出场了。

    杜教筛用来筛特定积性函数的前缀和。

    设目标函数为$f$,其前缀和为$S$

    $*$为狄利克雷卷积,相关证明在约数容斥有所交待。

    首先设函数:

    $$h=g*f$$

    那么:

    $$egin{array}{rcl}\ sumlimits_{i=1}^{n}h(i)&=&sumlimits_{i=1}^{n}sumlimits_{d|i}g(d)f(frac{i}{d})\&=&sumlimits_{d=1}^{n}g(d)sumlimits_{i=1}^{frac{n}{d}}f(i)\&=&sumlimits_{d=1}^{n}g(d)S(frac{n}{d})end{array}$$

    移项得到:

    $$S(n)=sumlimits_{i=1}^{n}h(i)-sumlimits_{d=2}^{n}g(d)S(frac{n}{d})$$

    这样的话如果我们的$h$和$g$的前缀和很好求,后面的部分就可以用数论分块来解决了。

    线筛预处理到$n^{frac{2}{3}}$,再采用记忆化搜索,复杂度是$O(n^{frac{2}{3}})$的,用哈希表跑的会很快。

    简单筛几个函数。

    7.$S(n)=sumlimits_{i=1}^{n}mu(i)$

    我们知道莫比乌斯函数的性质有:
    $$sumlimits_{d|n}mu(d)=e(n)$$

    换成狄利克雷卷积其实也就是:

    $$mu*I=e$$

    那么代入上面的式子:

    $$S(n)=sumlimits_{i=1}^{n}e(i)-sumlimits_{d=2}^{n}I(d)S(frac{n}{d})$$

    其实也就是:

    $$S(n)=1-sumlimits_{d=2}^{n}S(frac{n}{d})$$

    直接杜教筛即可。

    8.$S(n)=sumlimits_{i=1}^{n}imu(i)$

    设$f(i)=imu(i)$

    那么:

    $$f*id=sumlimits_{d|n}dmu(d)frac{n}{d}=nsumlimits_{d|n}mu(d)=ne(n)=e(n)$$

    代入上式:

    $$S(n)=sumlimits_{i=1}^{n}e(i)-sumlimits_{d=2}^{n}iS(frac{n}{d})=1-sumlimits_{d=1}^{n}dS(frac{n}{d})$$

    用个等差数列求和就可以一样筛了。

    9.$S(n)=sumlimits_{i=1}^{n}varphi(i)$

    欧拉反演的式子是:

    $$sumlimits_{d|n}varphi(d)=n$$

    换成狄利克雷卷积也就是:

    $$varphi*I=id$$

    代入上式:

    $$S(n)=sumlimits_{i=1}id(i)-sumlimits_{d=2}^{n}S(frac{n}{d})$$

    前面用等比数列求一下和就好了。

    10.$S(n)=sumlimits_{i=1}^{n}varphi(i^2)$

    设$f(n)=varphi(i^2)$

    发现:

    $$f(n)=nvarphi(n)$$

    那么:

    $$f*id=sumlimits_{d|n}(dvarphi(d))frac{n}{d}=nsumlimits_{d|n}phi(d)$$

    欧拉反演得到:

    $$f*id=n^2=id^2$$

    代入上式得到:

    $$S(n)=sumlimits_{i=1}^{n}id^2(i)-sumlimits_{d=2}^{n}dS(frac{n}{d})$$

    前面的东西用一下二次方自然数幂和,然后杜教筛即可。

    自然数幂和的公式是:

    $$frac{n(n+1)(2n+1)}{6}$$

    考场上如果忘了公式可以直接高斯消元得到这个多项式每一项的系数。

    筛法暂时这么多。

  • 相关阅读:
    数据结构-包含min函数的栈
    数据结构-顺时针打印矩阵
    数据结构-二叉树的镜像
    数据结构-树的子结构
    数据结构-合并两个排序的链表
    数据结构-反转链表
    数据结构-链表中倒数第K个节点
    数据结构-调整数组顺序使奇数位于偶数前面
    数据结构-在O(1)时间删除链表节点
    数据结构-打印1到最大的n位数
  • 原文地址:https://www.cnblogs.com/Lrefrain/p/11791013.html
Copyright © 2020-2023  润新知