积性函数的线性筛法

目录

目录地址

上一篇

下一篇


积性函数的转移关系

对于当前筛到的正整数 \(n\) ,若 \(fc_n\) 表示其最小质因数, \(p_i\) 表示第 \(i\) 个因数,我们需要筛的积性函数命名为 \(\boldsymbol f\)

那么,十分显然,对于 \(p_i<fc_n\) 时, \(\boldsymbol f(n\times p_i)=\boldsymbol f(n)\cdot \boldsymbol f(p_i)\)

如果 \(\boldsymbol f(p_i)\) 是一个关于 \(p_i\) (在对 \(m\) 取余意义下)的简单有理函数,则上述式子是可求的

简单有理函数可以理解为,简单多项式函数的商。简单多项式即多项式次数,相对筛的线性复杂度,可以视为常数的多项式

由于线性筛过程中会出现 \(p_i\leq fc_n\) ,故我们还需要考虑 \(p_i=fc_n\) 时的情况:

考虑若 \({\boldsymbol f(p^{k+1})\over \boldsymbol f(p^k)}=g(p),k\geq 1\) 为一个关于 \(p\) 的简单函数,则可以通过

\(\boldsymbol f(n\times fc_n)=\boldsymbol f({n\over fc_n^k})\cdot \boldsymbol f(fc_n^{k+1})=\boldsymbol f({n\over fc_n^k})\cdot g(fc_n)\cdot \boldsymbol f(fc_n^k)=\boldsymbol f(n)\cdot g(fc_n)\)

而快速的求出

故线性筛的条件为:

  1. \(\boldsymbol f(p)\) 需要为一个关于 \(p\) 的简单有理函数
  2. \(g(p)={\boldsymbol f(p^{k+1})\over \boldsymbol f(p^k)},k\geq 1\) 为一个关于 \(p\) 的简单函数

则线性筛的效果为:

\(\boldsymbol f(n\times p)=\begin{cases} \boldsymbol f(n)\cdot \boldsymbol f(p),p\nmid n \\\ \\ \boldsymbol f(n)\cdot g(p),p\mid n \end{cases}\)


线性筛的实现

首先我们需要构造好 \(\boldsymbol f\)\(g\) ,然后就可以通过上述式子快速实现线性筛了

inline int fp(int p){...}
inline int gp(int p){...}
int fc[MAXN],prime[MAXN],f[MAXN],cntprime;
void sieve(){
    f[1]=1;
    for(int i=2;i<=lim;i++){
        if(fc[i]==0){
            fc[i]=i;
            prime[++cntprime]=i;
            f[i]=fp(i);
        }
        for(int j=1;prime[j]<fc[i]&&prime[j]*i<=lim;j++){
            fc[i*prime[j]]=prime[j];
            f[i*prime[j]]=f[i]*f[prime[j]];
        }
        if(i*fc[i]<=lim){
            fc[i*fc[i]]=fc[i];
            f[i*fc[i]]=fc[i]*gp(fc[i]);
        }
    }
}

例如,当我们筛的为 \(\boldsymbol \varphi\)\(\boldsymbol f(p)=p-1,g(p)=p\)

\(\boldsymbol \mu\)\(\boldsymbol f(p)=-1,g(p)=0\)

当然,后期还有的题目涉及到的积性函数不是常见积性函数,但其若能找到满足上述条件的 \(\boldsymbol f\)\(g\) ,仍可以用线性筛筛出

posted @ 2020-03-13 10:27  JustinRochester  阅读(221)  评论(0编辑  收藏  举报