积性函数的线性筛法
目录
积性函数的转移关系
对于当前筛到的正整数 \(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)\)
而快速的求出
故线性筛的条件为:
- \(\boldsymbol f(p)\) 需要为一个关于 \(p\) 的简单有理函数
- \(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\) ,仍可以用线性筛筛出