【模板】【数学】欧拉函数

原文链接:https://blog.csdn.net/on_the_road344/article/details/45178243

对于正整数n,φ(n)是小于或等于n的正整数中,与n互质的数的数目;

欧拉函数就是用来求这个的。

公式: φ(x)=x(1-1/p(1))(1-1/p(2))(1-1/p(3))(1-1/p(4))…..(1-1/p(n)) 其中p(1),p(2)…p(n)为x 的所有质因数;x是正整数; φ(1)=1(唯一和1互质的数,且小于等于1)。注意:每种质因数只有一个。

有两种方法求,一种直接求,一种线性求。

 1 //直接求解欧拉函数
 2 int euler(int n){ //返回euler(n) 
 3      int res=n,a=n;
 4      for(int i=2;i*i<=a;i++){
 5          if(a%i==0){
 6              res=res/i*(i-1);//先进行除法是为了防止中间数据的溢出 
 7              while(a%i==0) a/=i;
 8          }
 9      }
10      if(a>1) res=res/a*(a-1);
11      return res;
12 }
13 
14 //筛选法打欧拉函数表 
15 #define Max 1000001
16 int euler[Max];
17 void Init(){ 
18      euler[1]=1;
19      for(int i=2;i<Max;i++)
20        euler[i]=i;
21      for(int i=2;i<Max;i++)
22         if(euler[i]==i)
23            for(int j=i;j<Max;j+=i)
24               euler[j]=euler[j]/i*(i-1);//先进行除法是为了防止中间数据的溢出 
25 }
View Code

 线性筛求欧拉函数

 1 void getphi()    
 2 {    
 3    int i,j;    
 4    phi[1]=1;    
 5    for(i=2;i<=N;i++)//相当于分解质因式的逆过程    
 6    {    
 7        if(!mark[i])    
 8            {    
 9              prime[++tot]=i;//筛素数的时候首先会判断i是否是素数。    
10              phi[i]=i-1;//当 i 是素数时 phi[i]=i-1    
11              }    
12        for(j=1;j<=tot;j++)    
13        {    
14           if(i*prime[j]>N)  break;    
15           mark[i*prime[j]]=1;//确定i*prime[j]不是素数    
16           if(i%prime[j]==0)//接着我们会看prime[j]是否是i的约数    
17           {    
18              phi[i*prime[j]]=phi[i]*prime[j];break;    
19           }    
20           else  phi[i*prime[j]]=phi[i]*(prime[j]-1);//其实这里prime[j]-1就是phi[prime[j]],利用了欧拉函数的积性    
21        }    
22    }    
23 } 
View Code

 

posted @ 2020-01-30 21:51  小布鞋  阅读(143)  评论(0)    收藏  举报