數論知識總結-線性篩
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; } } }