zoukankan      html  css  js  c++  java
  • 线性求欧拉函数

    我们都知道欧拉筛又称线性筛,能在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$,而不会影响$phi (x)=x*prod_{i=1}^n (1-frac{1}{p_i})$的右边$prod_{i=1}^n (1-frac{1}{p_i})$的部分,所以我们只要用$i*prime[j]$乘上右边$prod_{i=1}^n (1-frac{1}{p_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 }
  • 相关阅读:
    CSS3属性transform详解之(旋转:rotate,缩放:scale,倾斜:skew,移动:translate)
    MySQL<添加、更新与删除数据>
    MySQL<数据库和表的基本操作>
    MySQL<数据库入门>
    MySql阶段案例
    Mysql综合案例
    Mysql课后思考题
    Java课后思考题
    Java课后简答题
    超全面的JavaWeb笔记day23<AJAX>
  • 原文地址:https://www.cnblogs.com/Asika3912333/p/11313000.html
Copyright © 2011-2022 走看看