【模板】求欧拉函数值

一、线性筛求欧拉函数值--->复杂度O(n)

可以在筛出质数的同时求出每个数的欧拉函数值,主要公式有两条:

1.当i%prime[j]==0时:

phi[i*prime[j]]=i*prime[j]*(1-1/p1)*....*(1-1/prime[j])*...

由分解质因数易知phi[i]=i*(1-1/p1)*.....*(1-1/prime[j])*...

所以phi[i*prime[j]]=phi[i]*prime[j]

2.当i%prime[j]!=0时:

因为prime[j]是质数,所以很明显i与prime[j]互质,那么因为欧拉函数是积性函数,所以:

phi[i*prime[j]]=phi[i]*phi[prime[j]]=phi[i]*(prime[j]-1)

代码:

 1 #include<cstdio>
 2 const int N=1e5+5;
 3 int prime[N],phi[N],cnt=0;
 4 int n=100000;
 5 bool vis[N];
 6 void make_phi(){
 7     vis[0]=vis[1]=1;
 8     for(int i=2;i<=n;i++){
 9         if(!vis[i]){
10             prime[++cnt]=i;
11             phi[i]=i-1;
12         }
13         for(int j=1;j<=cnt&&prime[j]*i<=n;j++){
14             vis[i*prime[j]]=1;
15             if(i%prime[j]==0){
16                 phi[i*prime[j]]=phi[i]*prime[j];
17                 break;
18             }
19             else phi[i*prime[j]]=phi[i]*(prime[j]-1);
20         }
21     }
22 }
23 int main(){
24     make_phi();
25     for(int i=2;i<=10;i++)
26         printf("%d %d\n",i,phi[i]);
27     return 0;
28 }
线性筛求欧拉函数值

 二、求单个数的欧拉函数值--->复杂度O(sqrt(n))

代码:

 1 #include<cstdio>
 2 #include<cmath>
 3 int n;
 4 int get_phi(int x){
 5     int res=x;
 6     for(int i=2;i<=sqrt(x);i++){
 7         if(!(x%i)){
 8             res/=i;res*=i-1;
 9             while(!(x%i))x/=i;
10         }
11     }
12     if(x^1)res/=x,res*=x-1;
13     return res;
14 }
15 int main(){
16     scanf("%d",&n);
17     printf("%d",get_phi(n));
18     return 0;
19 }
求单个数的欧拉函数值

 

posted @ 2017-10-25 08:08  Child-Single  阅读(1052)  评论(0编辑  收藏  举报