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 }
  • 相关阅读:
    HDU 1800 Flying to the Mars 字典树,STL中的map ,哈希树
    字典树 HDU 1075 What Are You Talking About
    字典树 HDU 1251 统计难题
    最小生成树prim算法 POJ2031
    POJ 1287 Networking 最小生成树
    次小生成树 POJ 2728
    最短路N题Tram SPFA
    poj2236 并查集
    POJ 1611并查集
    Number Sequence
  • 原文地址:https://www.cnblogs.com/Asika3912333/p/11313000.html
Copyright © 2011-2022 走看看