标签:c11 ddl src return span int 防止 i++ for
phi[i]=从1到i与i互素的数的个数
公式: ,pi为x的质因子,n为x的质因子个数
例如:
12=2*2*3;
12=12*(1-1/2)*(1-1/3)
求单个的:
int phi(int x) { int ans=x; for(int i=2;i*i<=x;i++) { if(x%i==0) { ans=ans/i*(i-1); while(x%i==0)x/=i; } } if(x>1)ans=ans/x*(x-1); return ans; }
求很多个的:
特性:
1.若a为质数,phi[a]=a-1;
2.若a为质数,b与a不互素,即b%a==0,gcd(a,b)=a,那么phi[b*a]=phi[b]*a;
3.若a为质数,b与a互素,即b%a!=0,gcd(a,b)=1,phi[b*a]=phi[b]*phi[a]=phi[b]*(a-1);
由以上特性,我们需要先把质数找出来并存起来
利用找出来的质数和i把它们的乘积直接求出,类似于埃筛
break是为了防止一个数被求多次,我们总是让一个数被它最小的质因子筛去
const int maxn=1e5+10; int phi[maxn],prime[30000]; int cnt=0; void Euler() { phi[1]=1; for(int i=2;i<maxn;i++) { if(!phi[i]) { phi[i]=i-1; prime[cnt++]=i; } for(int j=0;j<cnt&&i*prime[j]<maxn;j++) { if(i%prime[j])phi[i*prime[j]]=phi[i]*(prime[j]-1); else { phi[i*prime[j]]=phi[i]*prime[j]; break; } } } }
标签:c11 ddl src return span int 防止 i++ for
原文地址:https://www.cnblogs.com/raincle/p/9606667.html