參考書籍:《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 * .... *pkak 為正整數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。
