欧拉函数

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 }
View Code
 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 }
View Code

 

 

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 }
View Code

 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 }
View Code

 

 

 

end

 

posted on 2014-08-03 16:09  gaolzzxin  阅读(146)  评论(0编辑  收藏  举报