线性筛筛质数
线性筛为什么可以做到线性,它让每个合数只被最小的质因数筛选一次而不发生重复筛选
1 2 3 4 5 6 7 8 9 10
| rep(i,2,n){ if(!vis[i]) pri[++cnt]=i; for(int j=1;j<=cnt and pri[j]*i<=1e8;j++){ int m=i*pri[j]; vis[m]=1; if(i%pri[j]==0) break; } }
|
线性筛求约数个数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| void init(){ a[1]=1,d[1]=1; int cnt=0; rep(i,2,1e7){ if(!vis[i]){ pri[++cnt]=i; a[i]=1;d[i]=2; } for(int j=1;j<=cnt and i*pri[j]<=1e7;j++){ int m=i*pri[j]; vis[m]=1; if(i%pri[j]==0){ a[m]=a[i]+1; d[m]=d[i]/a[m]*(a[m]+1); break; }else{ a[m]=1; d[m]=d[i]*2; } } } }
|
线性筛求约数和
a[i]是最小质因数的约数和
d[i]是函数值
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| void init(){ int cnt=0; rep(i,2,1e7){ if(!vis[i]){ pri[++cnt]=i; a[i]=d[i]=i+1; } for(int j=1;j<=cnt and i*pri[j]<=1e7;j++){ int m=i*pri[j]; vis[m]=1; if(i%pri[j]==0){ a[m]=a[i]*p[j]+1; d[m]=d[i]/a[i]*a[m] break; }else{ a[m]=p[j]+1; d[m]=d[i]*a[m]; } } } }
|
线性筛求莫比乌斯函数
莫比乌斯函数:
包含相同质因子为0
不同质因数为偶数个为1,奇数为-1
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| void init(){ int cnt=0; rep(i,2,1e7){ if(!vis[i]){ pri[++cnt]=i; mu[i]=-1; } for(int j=1;j<=cnt and i*pri[j]<=1e7;j++){ int m=i*pri[j]; vis[m]=1; if(i%pri[j]==0){ mu[m]=0;s break; }else{ mu[m]=-mu[i]; } } } }
|
莫比乌斯反演
设任意算术函数f, 其和函数为
即n的所有正因数的函数和称为和函数
莫比乌斯函数就是和函数到原函数的反向过程
线性筛与积性函数
其实上诉问题,因子和 和约数个数 都是积性函数
积性函数?对于互为质数的正整数p,q有
积性函数都可以用线性筛求解1~n的所有函数值
O(n)求1~n的欧拉函数是一个比较简单但直观的例子,所以线性筛也被称为欧拉筛
欧拉函数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| void solve(){ int cnt=0; rep(i,2,n){ if(!vis[i]){ phi[i]=i-1; pr[++cnt]=i; } for(int j=1;j<=cnt and pr[j]<=n/i;j++){ int m=i*pr[j]; vis[m]=1; if(i%pr[j]==0){ phi[m]=phi[i]*pr[j]; break; }else{ phi[m]=phi[i]*phi[pr[j]]; } } } }
|
完全积性函数
华华给月月出题
幂函数对于任何的p,q都满足
被称为完全积性函数,不需要单独考虑遍历值不为最小质因数的情况
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| cin>>n; f[1]=1; int cnt=0; rep(i,2,n){ if(!vis[i]){ pri[++cnt]=i; f[i]=qpow(i,n,p)%p; } for(int j=1;j<=cnt and pri[j]<=n/i;j++){ vis[i*pri[j]]=1; f[i*pri[j]]=f[i]*f[pri[j]]%p; if(i%pri[j]==0) break; } }
|