欧拉函数
欧拉函数:<=n中与n互质数的个数
phi[1]=1,phi[2]=1;
1)单值:按题意暴力,
int euler(int n){ int res=n; for(int i=2;i*i<=n;i++){//是i*i到n if(n%i==0){ res=res/i*(i-1); while(n%i==0){ n=n/i; } } } if(n>1) res=res/n*(n-1);//防止最终还有剩下因子 return res; }
2)埃筛法:先用euler[i]数组内值代表初始状态(是否已被操作)
void init(){ for(int i=2;i<=n;i++) phi[i]=i; for(int i=2;i<=n;i++) if(phi[i]==i){ phi[i]=i-1; for(int j=2*i;j<=n;j+=i) phi[j]-=phi[j]/i; } }
3.线性筛法
void init(){ phi[1]=1; for(int i=2;i<=n;i++){ if(!phi[i]) prime[++cnt]=i,phi[i]=i-1; for(int j=1;j<=cnt&&i*prime[j]<=n;j++){ if(i%prime[j]==0) {phi[i*prime[j]]=phi[i]*prime[j];break;} else phi[i*prime[j]]=phi[i]*(prime[j]-1); } } }
性质:
1) 积性函数
若m,n互质,
特:当n为奇数时,
2)n为质数
2)n为质数
e.g: UVA11426
求gcd(1,2)+gcd(1,3)+···+gcd(1,n)+gcd(2,3)+gcd(2,4)+ ···+gcd(2,n)+···+gcd(n-1,n)
利用性质:gcd(a,b)=p 等价于 gcd(a/p,b/p)=1;
将欧拉函数前缀和,同时注意将phi[1]=0(此时找到的都是小于本身的数),而欧拉函数是包括本身的。
#include<bits/stdc++.h> #define ll long long using namespace std; const int N=4001000; ll phi[N],n,ans; void init(){ for(int i=2;i<=n;i++) phi[i]=i; for(int i=2;i<=n;i++) if(phi[i]==i){ phi[i]=i-1; for(int j=2*i;j<=n;j+=i) phi[j]-=phi[j]/i; } for(int i=1;i<=n;i++) phi[i]+=phi[i-1]; } int main(){ freopen("work.in","r",stdin); freopen("work.out","w",stdout); scanf("%lld",&n);init(); for(int i=1;n/i>1;i++) ans+=i*phi[n/i]; printf("%lld",ans);return 0; }