欧拉(Euler)筛法求素数
时间复杂度为O(n)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| void init(){ phi[1]=1; for(int i=2;i<MAXN;i++){ if(!vis[i]){ phi[i]=i-1; pri[cnt++]=i; } for(int j=0;j<cnt;j++){ if(1LL*i*pri[j]>=MAXN)break; vis[i*pri[j]]=1; if(i%pri[j]){ phi[i*pri[j]]=phi[i]*(pri[j]-1); } else { phi[i*pri[j]]=phi[i]*pri[j]; break; } } } }
|
注意到筛法求素数的同时也得到了每个数的最小质因子
筛法求欧拉函数
对于一个数n,φ(n)的值为1−pi1的累乘再乘上n,其中pi为每一个不同的质因子
1 2 3 4 5 6 7 8 9 10
| void get_phi(int n){ for(int i=2;i<=n;i++)phi[i]=0; phi[1]=1; for(int i=2;i<=n;i++) if(!phi[i]) for(int j=i;j<=n;j+=i){ if(!phi[j])phi[j]=j; phi[j]=phi[j]/i*(i-1); } }
|
筛法求莫比乌斯函数
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| void get_mu(){ mu[1]=1; for(int i=2;i<MAXN;i++){ if(!v[i])mu[i]=-1,p[tot++]=i; for(int j=0;j<tot&&i<=MAXN/p[j];j++){ v[i*p[j]]=1; if(i%p[j]==0){ mu[i*[j]]=0; break; } mu[i*p[j]]=-mu[i]; } } }
|
筛法求约数个数
d[i]表示i的约数个数,num[i]表示i的最小质因子出现次数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| void get_d(){ d[1]=1; for(int i=2;i<MAXN;i++){ if(!v[i])v[i]=1,p[tot++]=i,d[i]=2,num[i]=1; for(int j=0;j<tot&&i<=MAXN/p[j];j++){ v[p[j]*i]=1; if(i%p[j]==0){ num[i*p[j]]=num[i]+1; d[i*p[j]]=d[i]/(num[i]+1)*(num[i*p[j]]+1); break; } else { num[i*p[j]]=1; d[i*p[j]]=d[i]*2; } } } }
|
筛法求约数和
f[i]表示i的约数和, g[i]表示i的最小质因子p的p0+p1+⋯+pn
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| void get_sum(){ g[1]=f[1]=1; for(int i=2;i<MAXN;i++){ if(!v[i])v[i]=1,p[tot++]=i,g[i]=i+1,f[i]=i+1; for(int j=0;j<tot&&i<=MAXN/p[j];j++){ v[p[j]*i]=1; if(i%p[j]==0){ g[i*p[j]]=g[i]*p[j]+1; f[i*p[j]]=f[i]/g[i]*g[i*p[j]]; break; } else { f[i*p[j]]=f[i]*f[p[j]]; g[i*p[j]]=1+p[j]; } } } }
|