歐拉函數一些定理的證明


參考書籍:《ACM-ICPC程序設計系列--數論及應用》

歐拉函數φ(n)指不超過n且與n互質的正整數的個數,其中n是一個正整數。

歐拉函數的性質:它在整數n上的值等於對n進行素因子分解后,所有的素數上的歐拉函數之積。

 

定義:

  1.定義在所有正整數上的函數稱為算數函數

    2.算法函數f如果滿足對任意兩個互質的正整數n和m,均有f(mn)=f(n)f(m),就稱為積性函數。如果對任意的兩個正整數n和m,均有f(mn)=f(m)f(n),就稱為完全積性函數。

(歐拉函數就是一個積性函數證明:http://www.cnblogs.com/372465774y/archive/2012/10/16/2726282.html

 

定理:

  1.如果f是一個積性函數,對任意正整數n有素數冪分解n=p1a1  * p2a2  * .... *psas,那么f(n)=f(p1a1)*f(p2a2)*...*f(psas)。

    2.如果p是素數,那么φ(n)=p-1;反之如果p是一個正整數且滿足φ(p)=p-1,那么p是素數。  

    3.設p是素數,a是一個正整數,那么φ(pa)=pa-pa-1

證明:比pa小的數有pa-1個,因為pa只有一個素因子p,其中與p不互質的有pa-1-1(分別是1*p,2*p,3*p....(pa-1-1)*p )

所以φ(pa)=(pa-1)-(pa-1-1)=pa-pa-1  證畢。

    4.設n和m是互質的正整數,那么φ(nm)=φ(n)φ(m)  (因為歐拉函數是積性函數嘛,上面有證明)。

         5.設n=p1a1  * p2a2  * .... *pka為正整數n的素數冪分解,那么

        φ(n)=n * (1-1/p1)*(1-1/p2)*....*(1-1/pk)  (算法的核心)

證明:由定理4可知φ(n)=φ(p1a1)*φ(p2a2)*.....*φ(pkak

  再由定理3得φ(n)=(p1a1-p1a1-1)*(p2a2-p2a2-1)*.....*(pkak-pkak-1

  提取因素得φ(n)=p1a1 (1-1/p1)*p2a2(1-1/p2)*pkak(1-1/pk

  所以φ(n)=n * (1-1/p1)*(1-1/p2)*....*(1-1/pk) 證畢。

推論:當n為奇數時,有φ(2n)=φ(n);

證明:設n=p1a1  * p2a2  * .... *pkak(假設p1是2)    則 φ(n)=n * (1-1/p1)*(1-1/p2)*....*(1-1/pk)

那么2n=p1a1+1  * p2a2  * .... *pkak  即φ(2n)=(p1a1+1-p1a1)*(p2a2-p2a2-1)*.....*(pkak-pkak-1

                          =p1a1 (p1-1)*p2a2(1-1/p2)*pkak(1-1/pk

                          =n * (p1-1)*(1-1/p2)*....*(1-1/pk)

                          =n *(1-1/p2)*....*(1-1/pk) 

因為n為奇數所以沒有2這個素因子,即a1=0. 所以φ(n)=n *(1-1/p2)*....*(1-1/pk)=φ(2n) 證畢。

         6.設n是一個大於2的正整數,那么φ(n)是偶數

證明:因為φ(n)=(p1a1-p1a1-1)*(p2a2-p2a2-1)*.....*(pkak-pkak-1) 

情況一:n有2這個素因子時,piai-piai-1(令pi=2)一定是偶數(偶數減偶數嘛)φ(n)是一個偶數的倍數當然是偶數了。

情況二 : n沒有2這個素因子,一定存在一個奇素因子,piai-piai-1為偶數(因為 p^a與p^(a-1) 均為奇數)

    7.∑d|nφ(d)=n  (即n的因子的歐拉函數值之和為n)

證明:

情況一:n=1時顯然成立

情況二:n≠1時,

 

 

定理基本介紹完了,我們來看代碼:

如果根據定理5直接實現:

int phi(int n)
{
    int rea=n;
    for(int i=2;i<=n;i++)
    {
        if(n%i==0)//找到素因子 
        {
            rea=rea/i*(i-1);
            while(n%i==0)//把該素因子全部約掉 
                n/=i;    
        }
    }
    return rea;
}

時間復雜度為O(n),還可以優化降到O(√n),因為任何一個合數都至少有一個不大於√n的素因子,所以只需要遍歷√n即可

int phi(int n)
{
    int rea=n;
    for(int i=2;i*i<=n;i++)//變化的地方 
    {
        if(n%i==0)
        {
            rea=rea/i*(i-1);
            while(n%i==0)
                n/=i;    
        }
    }
    if(n>1)//有可能有一個大於√n素因子 
        rea=rea/n*(n-1);
    return rea;
}

如果最后n>1,為什么一定是一個大於√n的素因子。簡單說下,因為不可能是兩個及以上素因子的乘積。因為倒數第二個素因子一定小於√n。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM