zoukankan      html  css  js  c++  java
  • 【转】欧拉函数

    链接:http://www.cnblogs.com/yefeng1627/archive/2013/01/02/2842492.html

    欧拉函数直接计算公式

      欧拉函数的定义: E(N)= (  区间[1,N-1] 中与 N 互质的整数个数).

      对于 积性函数 F(X*Y),当且仅当 GCD(X,Y)= 1 时, F(X*Y) = F(X)* F(Y)

      任意整数可因式分解为如下形式:

            其中( p1, p2 ... pk 为质数, ei 为次数 )  

      所以

        

      因为 欧拉函数 E(X)为积性函数, 所以

         

      对于    , 我们知道 因为pi 为质数,所以 [ 1, pi-1 ] 区间的数都与 pi 互质

      对于 区间[ 1,   ]  ,共有  个数, 因为  只有一个质因子,

      所以与  约数大于1 的必定包含 质因子   , 其数量为   

      

        所以      

      又 E(N)为积性函数,所以可得 :

        

      又因为       其中( p1, p2 ... pk 为质数, ei 为次数 )  

             但是此计算公式,除法过多,所以计算速度较慢

      在程序中利用欧拉函数如下性质,可以快速求出欧拉函数的值 ( P为N的质因子 )

        若(N%P==0 && (N/P)%P==0) 则有:E(N)=E(N/P)*P;
     
        若(N%P==0 && (N/P)%P!=0) 则有:E(N)=E(N/P)*(P-1);

    求单个数的欧拉函数:

    long long eular(long long n)
    {
        int i;
        long long ans=n;
        for(i=2;i*i<=n;i++)
        {
            if(n%i==0)
            {
                ans-=ans/i;
                while(n%i==0)
                    n/=i;
            }
        }
        if(n>1)ans-=ans/n;
        return ans;
    }
    

    筛法欧拉函数:

    int eular[MAXN+1];
    void getEular()
    {
        int i,j;
        memset(eular,0,sizeof(eular));
        eular[1]=1;
        for(i=2;i<=MAXN;i++)
        {
            if(!eular[i])
                for(j=i;j<=MAXN;j+=i)
                {
                    if(!eular[j])
                        eular[j]=j;
                    eular[j]=eular[j]/i*(i-1);
                }
        }
    }

    线性筛(同时得到欧拉函数和素数表)

    bool check[MAXN+10];
    int phi[MAXN+10];
    int prime[MAXN+10];
    int tot;
    void phi_and_prime_table(int N)
    {
        int i,j;
        memset(check,false,sizeof(check));
        phi[1]=1;
        tot=0;
        for(i=2;i<=N;i++)
        {
            if(!check[i])
            {
                prime[tot++]=i;
                phi[i]=i-1;
            }
            for(j=0;j<tot;j++)
            {
                if(i*prime[j]>N)break;
                check[i*prime[j]]=true;
                if(i%prime[j]==0)
                {
                    phi[i*prime[j]]=phi[i]*prime[j];
                    break;
                }
                else
                    phi[i*prime[j]]=phi[i]*(prime[j]-1);
            }
        }
    }
    

      

  • 相关阅读:
    面向对象三 组合 特殊成员
    面向对象二 成员 嵌套
    面向对象
    模块和包
    异常处理
    os模块和序列化模块
    常用模块一
    常用模块 re模块
    内置函数二
    Algs4-2.2.14归并有序的队列
  • 原文地址:https://www.cnblogs.com/vwqv/p/5768571.html
Copyright © 2011-2022 走看看