欧拉函数的代码实现

数论&&组合数学 专栏收录该内容
49 篇文章 0 订阅

欧拉定理证明出门左转

线性筛素数出门直走

单个筛欧拉函数由欧拉函数公式直接在给n分解质因数时连乘就好

代码

int phi(int n)
{ 
     int res=n,a=n;  
     for(int i=2;i*i<=a;i++)
	 {  
         if(a%i==0)
		 {  
             res=res/i*(i-1);//先除后乘防止溢出   
             while(a%i==0) a/=i;  
         }  
     }  
     if(a>1) res=res/a*(a-1);  
     return res;  
}  

先说一个近似线性筛的筛法

void Euler()
{
    phi[1]=1;
    for(int i=2;i<M;i++)
        if(!phi[i])//没有被筛过说明是质数 
            for(int k=i;k<M;k+=i)
	    {
                if(!phi[k]) phi[k]=k;
                phi[k]=phi[k]/i*(i-1);//欧拉函数公式的实现 
            }
    return ; 
}

线性筛欧拉函数建立在线性筛素数的基础之上

重要性质:若i%p=0,p是素数,那么φ(i*p)=φ(i)*p,若i%p!=0,p是素数,那么φ(i*p)=φ(i)*(p-1)

证明(该证明可能存在错误):当i%p=0时,若GCD(a,b)=1,则GCD(a+b,b)=1,由此可以得出,将φ(i)中的数每个加i,则会得到另外φ(i)个数,若以此类推,累加(p-1)次,则一共有p*φ(i)个数与i互质,因为p是i的质因子,所以与i互质的数必定与i*p互质,所以φ(i*p)=φ(i)*p;当i%p!=0时,发现i,p互质,且p为素数,所以φ(p)等于p-1,由积性函数性质可得φ(i*p)=φ(i)*φ(p)=φ(i)*(p-1)

代码

void getphi()    
{    
   int vis[M],phi[M],pri[M],tot;   
   for(int i=2;i<=n;i++)   
   {    
     	if(!vis[i])//先判断i是不是素数    
    	{    
            pri[++tot]=i; 
            phi[i]=i-1;//当 i 是素数时小于i的所有大于零的数都和i互素    
        }    
       	for(int k=1;k<=tot;k++)    
       	{    
          	if(i*pri[k]>M)  break;    
          	vis[i*pri[k]]=1;//按照筛素数,筛掉i的倍数 
          	if(i%pri[k]==0)//如果有一个质数是i的因子,那么phi(i*pri[k])=phi(i)*pri[k]  
          	{    
             	phi[i*pri[k]]=phi[i]*pri[k];break;    
          	}    
          	else  phi[i*pri[k]]=phi[i]*(phi[pri[k]]);
			  //利用了欧拉函数的积性,两个数互质,那么phi(i*k)=phi(i)*phi(pri[k])   
       	}    
   }    
}    



展开阅读全文
  • 0
    点赞
  • 0
    评论
  • 1
    收藏
  • 一键三连
    一键三连
  • 扫一扫,分享海报

打赏
文章很值,打赏犒劳作者一下
相关推荐
©️2020 CSDN 皮肤主题: 技术黑板 设计师:CSDN官方博客 返回首页

打赏

AcerMo

你的鼓励将是我创作的最大动力

¥2 ¥4 ¥6 ¥10 ¥20
输入1-500的整数
余额支付 (余额:-- )
扫码支付
扫码支付:¥2
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值