数论知识总结-线性筛
NOIP爆零の蒟蒻又来学数论辣函数
注:下文p都是质数spa
线性筛素数
也叫欧拉筛?code
int pr[maxn];bool flg[maxn]; int main(){ for(rg int i=2;i<maxn;++i){ if(!flg[i])pr[++pr[0]]=i; for(rg int j=1;i*pr[j]<=n&&j<=pr[0];++j){ flg[i*pr[j]]=1; if(i%pr[j]==0)break;//重点 } } }
这样筛的话,若合数$n=p_1^{a_1}p_2^{a_2}\cdots p_k^{a_k}(p_1<p_2<\cdots<p_k)$,则$n$会在$i=n/p_1,pr[j]=p_1$处被筛去,也只会在这里被筛去。也就是说,每一个数都会被它最小的质因子筛去。if(i%pr[j]==0)break;
这句话保证了复杂度。class
没了?im
线性筛积性函数
积性函数就是定义在$\mathbb{Z^+}$上的函数,且对于任何一对互质的正整数$x,y$知足$f(x)f(y)=f(xy)$,根据定义必定知足$f(1)=1$总结
然而我只会一丁点,之后再补di
筛这个必须深入理解线性筛的过程co
线性筛欧拉函数
有点点麻烦。time
首先,$\phi(p)=p-1$math
而后,将合数$n$分解成$n=px$(p是n最小的质因子),
若$p\nmid x$则$\phi(n)=\phi(x)\times\frac{p-1}{p}\times\frac{n}{x}=\phi(x)\times(p-1)$
不然$\phi(n)=\phi(x)\times\frac{n}{x}=\phi(x)\times p$
int phi[maxn],pr[maxn];bool flg[maxn]; main(){ phi[1]=1; for(rg int i=2;i<maxn;++i){ if(!flg[i])pr[++pr[0]]=i,phi[i]=i-1; for(rg int j=1;i*pr[j]<maxn&&j<=pr[0];++j){ flg[i*pr[j]]=1; if(i%pr[j]==0){phi[i*pr[j]]=phi[i]*pr[j];break;} phi[i*pr[j]]=phi[i]*(pr[j]-1); } } }
线性筛莫比乌斯函数
这个很好办。
首先,$\mu(p)=-1$
而后,将合数$n$分解成$n=px$(p是n最小的质因子),
若$p\nmid x$则$\mu(n)=-\mu(x)$
不然$\mu(n)=0$
int mu[maxn],pr[maxn];bool flg[maxn]; main(){ mu[1]=1; for(rg int i=2;i<maxn;++i){ if(!flg[i])pr[++pr[0]]=i,mu[i]=-1; for(rg int j=1;i*pr[j]<maxn&&j<=pr[0];++j){ flg[i*pr[j]]=1; if(i%pr[j]==0){mu[i*pr[j]]=0;break;} mu[i*pr[j]]=-mu[i]; } }
线性筛前N个数的约数个数
极其麻烦。
这个好像叫$d$函数
看$d=(a_1+1)(a_2+1)\cdots(a_k+1)$
然而还不行,你还要记这个数的$a_1$(定义在上面)记为$f$
首先,$d(p)=2,f(p)=1$
而后,将合数$n$分解成$n=px$(p是n最小的质因子),
若$p\nmid x$则$d(n)=2d(x),f(n)=1$(d乘2至关因而要不要新选p)
不然$f(n)=f(x)+1,d(n)=d(x)*\frac{f(n)+1}{f(x)+1}$
(我好像把这个套路粘了两遍)
int pr[maxn],d[maxn],f[maxn];bool flg[maxn]; int main(){ int n=gi(); for(rg int i=1;i<=n;++i)d[i]=1; for(rg int i=2;i<=n;++i){ if(!flg[i])pr[++pr[0]]=i,d[i]=2,f[i]=1; for(rg int j=1;i*pr[j]<=n&&j<=pr[0];++j){ flg[i*pr[j]]=1; if(i%pr[j]==0){ f[i*pr[j]]=f[i]+1; d[i*pr[j]]=d[i]/(f[i]+1)*f[i*pr[j]]; break; } f[i*pr[j]]=1; d[i*pr[j]]=d[i]*2; } } }