欧拉函数
The Euler function http://acm.hdu.edu.cn/showproblem.php?pid=2824
筛法
1 #include<cstdio> 2 #include<cstring> 3 #define mt(a,b) memset(a,b,sizeof(a)) 4 typedef __int64 LL; 5 const int M=3000010; 6 int phi[M];//小于i并且与i互素的个数 7 int pri[M],pricnt; 8 void sieve_phi(){//筛法求欧拉函数phi 9 pricnt=0; 10 mt(phi,0); 11 phi[1]=1; 12 for(int i=2;i<M;i++){ 13 if(!phi[i]){ 14 pri[pricnt++]=i; 15 phi[i]=i-1; 16 } 17 for(int j=0;pri[j]*i<M;j++){ 18 if(i%pri[j]){ 19 phi[i*pri[j]]=phi[i]*(pri[j]-1); 20 } 21 else{ 22 phi[i*pri[j]]=phi[i]*pri[j]; 23 break; 24 } 25 } 26 } 27 } 28 int main() { 29 sieve_phi(); 30 int x,y; 31 while(~scanf("%d%d",&x,&y)){ 32 LL ans=0; 33 for(int i=x;i<=y;i++){ 34 ans+=phi[i]; 35 } 36 printf("%I64d\n",ans); 37 } 38 return 0; 39 }
1 #include<cstdio> 2 #include<cstring> 3 #define mt(a,b) memset(a,b,sizeof(a)) 4 typedef __int64 LL; 5 const int M=3000010; 6 int pri[M],mark[M],pricnt;//mark[i]存i的最小因子,素数时mark[i]==i 7 void sieve_primes() { //筛素数 8 pricnt=0; 9 mt(mark,0); 10 mark[0]=mark[1]=1; 11 for(int i=2; i<M; i++) { 12 if(!mark[i]) pri[pricnt++]=mark[i]=i; 13 for(int j=0; pri[j]*i<M; j++) { 14 mark[i*pri[j]]=pri[j]; 15 if(!(i%pri[j])) break; 16 } 17 } 18 } 19 int phi_before_sieve(int n){//筛素数后求n的欧拉函数n<M 20 int ret=n,t; 21 while((t=mark[n])!=1){ 22 ret=ret/t*(t-1); 23 while(mark[n]==t) n/=mark[n]; 24 } 25 return ret; 26 } 27 int main() { 28 sieve_primes(); 29 int x,y; 30 while(~scanf("%d%d",&x,&y)) { 31 LL ans=0; 32 for(int i=x;i<=y;i++){ 33 ans+=phi_before_sieve(i); 34 } 35 printf("%I64d\n",ans); 36 } 37 return 0; 38 }
Farey Sequence http://poj.org/problem?id=2478
1 #include<cstdio> 2 #include<cstring> 3 #define mt(a,b) memset(a,b,sizeof(a)) 4 typedef __int64 LL; 5 const int M=1000010; 6 int phi[M];//小于i并且与i互素的个数 7 int pri[M],pricnt; 8 void sieve_phi(){//筛法求欧拉函数phi 9 pricnt=0; 10 mt(phi,0); 11 phi[1]=1; 12 for(int i=2;i<M;i++){ 13 if(!phi[i]){ 14 pri[pricnt++]=i; 15 phi[i]=i-1; 16 } 17 for(int j=0;pri[j]*i<M;j++){ 18 if(i%pri[j]){ 19 phi[i*pri[j]]=phi[i]*(pri[j]-1); 20 } 21 else{ 22 phi[i*pri[j]]=phi[i]*pri[j]; 23 break; 24 } 25 } 26 } 27 } 28 LL sum[M]; 29 int main() { 30 sieve_phi(); 31 sum[1]=0; 32 for(int i=2;i<M;i++){ 33 sum[i]=sum[i-1]+phi[i]; 34 } 35 int n; 36 while(~scanf("%d",&n),n){ 37 printf("%I64d\n",sum[n]); 38 } 39 return 0; 40 }
Relatives http://poj.org/problem?id=2407
1 #include<cstdio> 2 int phi(int n){//求n的欧拉函数 3 int ret=n; 4 for(int i=2;i*i<=n;i+=(i==2)?1:2){ 5 if(!(n%i)){ 6 ret=ret/i*(i-1); 7 while(!(n%i)) n/=i; 8 } 9 } 10 if(n>1) ret=ret/n*(n-1); 11 return ret; 12 } 13 int main() { 14 int n; 15 while(~scanf("%d",&n),n){ 16 printf("%d\n",phi(n)); 17 } 18 return 0; 19 }
end