线性求欧拉函数

我们都知道欧拉筛又称线性筛,能在O(n)的时间复杂度内筛出n以内的所有质数,而我们只要在线性筛的代码上改良一下就能求出n以内所有数的欧拉函数了。
筛质数时,设外层在枚举i,内层枚举到prime[j],这时有两种情况:

  1. i%prime[j]不为0,也就是说,i与j互质,根据欧拉函数的积性可得phi[ i * prime[j] ]=phi[ i ]*phi[ prime[j] ]而这些是前面求出来的,可以直接拿来推。
  2. i%prime[j]为0,也就是说,i内有一个质因子是prime[j],不过没有关系,这只是在i的质因数分解prime[j]的指数加1,而不会影响 的右边1-1/p的部分,所以我们只要用i * prime[j] 乘上右边部分即可,phi[i]=i * 右边部分,即可推出phi[i * prime[j]]=i *  prime[j] * phi[i]/i=prime[j] * phi[i]。

附上代码:
    

 1 int phi[];
 2 int notprime[],prime[];
 3 int cnt;
 4 void getphi(int n){
 5     notprime[0]=notprime[1]=1;
 6     phi[1]=0,phi[2]=1;
 7     for(int i=2;i<=n;++i){
 8         if(!primenot[i]){
 9             phi[i]=i-1;//质数的欧拉函数值为该质数减一
10             prime[++cnt]=i;
11         }
12         for(int j=1;j<=cnt&&prime[j]*i<=n;++j){
13             notprime[prime[j]*i]=1;
14             if(i%prime[j]) phi[prime[j]*i]=phi[prime[j]]*phi[i];//互质
15             else {//不互质
16                 phi[prime[j]*i]=prime[j]*phi[i];
17                 break;
18             }
19         }
20     }
21 }

 

转载于:https://www.cnblogs.com/Asika3912333/p/11313000.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值