歐拉函數知識點總結及代碼模板及歐拉函數表
阿新 • • 發佈:2017-10-07
算法實現 for 表示 滿足 情況 += radi 分析 因子
若n是質數p的k次冪,φ(n)=p^k-p^(k-1)=(p-1)p^(k-1),因為除了p的倍數外,其他數都跟n互質。
設n為正整數,以 φ(n)表示不超過n且與n互素的正整數的個數,稱為n的歐拉函數值,這裏函數φ:N→N,n→φ(n)稱為歐拉函數。
歐拉函數是積性函數——若m,n互質,φ(mn)=φ(m)φ(n)。
特殊性質:當n為奇數時,φ(2n)=φ(n), 證明與上述類似。
算法實現與分析:
求解歐拉函數的值可用φ(x)=x(1-1/p1)(1-1/p2)(1-1/p3)(1-1/p4)…..(1-1/pn),容易知道要對n進行素因子分解。
(1)直接實現
歐拉函數是少於或等於n的數中與n互質的數的數目。
歐拉函數的性質:它在整數n上的值等於對n進行素因子分解後,所有的素數冪上的歐拉函數之積。
歐拉函數的值 通式:φ(x)=x(1-1/p1)(1-1/p2)(1-1/p3)(1-1/p4)…..(1-1/pn),其中p1, p2……pn為x的所有質因數,x是不為0的整數。φ(1)=1(唯一和1互質的數(小於等 於1)就是1本身)。 (註意:每種質因數只一個。比如12=2*2*3那麽φ(12)=12*(1-1/2)*(1-1/3)=4)
推論:當n為奇數時,有φ(2n)=φ(n)。
int oula(int n) { int rea=n; for(int i=2; i<=n; i++) if(n%i==0)//第一次找到的必為素因子 { rea=rea-rea/i; do n/=i;//把該素因子全部約掉 while(n%i==0); } return rea; }
這個函數的復雜度為O(n),如果n達到1000000000,肯定會超時,由於任何一個合數都至少有一個不大於根號n的素因子,所以只需遍歷到根號n即可,這樣復雜度降為O(√¯n)
下面是優化代碼:
int oula(int n) { int rea=n; for(int i=2; i*i<=n; i++) if(n%i==0)//第一次找到的必為素因子 { rea=rea-rea/i; do n/=i;//把該素因子全部約掉 while(n%i==0); } if(n>1) rea=rea-rea/n; return rea; }
(2)素數表實現
先把50 000以內的素數用篩選法選出來並保存,以方便歐拉函數使用,這樣,在不考慮篩選法的時間復雜度,而單純看歐拉函數,其復雜度為O(x),x為O(√¯n)以內素數的個數。
bool boo[50000]; int p[20000]; void prim() { memset(boo,0,sizeof(boo)); boo[0]=boo[1]=1; int k=0; for(int i=2; i<50000; i++) { if(!boo[i]) p[k++]=i; for(int j=0; j<k&&i*p[j]<50000; j++) { boo[i*p[j]=1; if(!(i%p[j])) break; } } }//篩選法打表 int phi(int n) { int rea=n; for(int i=0; p[i]*p[i]<=n; i++)//對於一些不是素數的可不遍歷 if(n%p[i]==0) { rea=rea-rea/n; do n/=p[i]; while(n%p[i]==0); } if(n>1) rea=rea-rea/n; return rea; }
(3)遞推求歐拉函數
如果頻繁的使用歐拉函數值,就需要預先打表,下面介紹遞推求歐拉公式的方法。
可預先之所有數的歐拉函數值都為她本身,有定理可知,如果p是一個正整數且滿足φ(p)=p-1;那麽p是素數,在遍歷過程中如果遇到歐拉函數與自身相等的情況。那麽說明該數為素數,把這個數的歐拉函數值改變,同時也把能被素因子整除的數改變。
for(i=1; i<=maxn; i++) p[i]=i; for(i=2; i<=maxn; i+=2) p[i]/=2; for(i=3; i<=maxn; i+=2) if(p[i]==i) { for(j=i; j<=maxn; j+=i) p[j]=p[j]/i*(i-1); }
噶嗚~附上歐拉函數表:
2-100歐拉函數表 n φ(n) 2 1 3 2 4 2 5 4 6 2 7 6 8 4 9 6 10 4 11 10 12 4 13 12 14 6 15 8 16 8 17 16 18 6 19 18 20 8 21 12 22 10 23 22 24 8 25 20 26 12 27 18 28 12 29 28 30 8 31 30 32 16 33 20 34 16 35 24 36 12 37 36 38 18 39 24 40 16 41 40 42 12 43 42 44 20 45 24 46 22 47 46 48 16 49 42 50 20 51 32 52 24 53 52 54 18 55 40 56 24 57 36 58 28 59 58 60 16 61 60 62 30 63 36 64 32 65 48 66 20 67 66 68 32 69 44 70 24 71 70 72 24 73 72 74 36 75 40 76 36 77 60 78 24 79 78 80 32 81 54 82 40 83 82 84 24 85 64 86 42 87 56 88 40 89 88 90 24 91 72 92 44 93 60 94 46 95 72 96 32 97 96 98 42 99 60 100 40歐拉函數知識點總結及代碼模板及歐拉函數表