什么是歐拉函數
歐拉函數是小於x的整數中與x互質的數的個數,特殊的 φ(1) = 1.
如何計算歐拉函數
其中p1,p2,.....pn為x的所有質因數,x是正整數。
歐拉函數的幾個性質
1、對於質數p φ(p)=p-1.
2、若p為質數,n = pk,則 φ(n) = pk - pk-1
3、歐拉函數是積性函數,但不是完全積性函數(不互質也滿足等式)。若m,n互質,則φ(m*n)=φ(m)*φ(n).
4、當n>2時,φ(n)* n / 2 (n > 1).
5、小於n且與n互質的數的總和為:φ(n)* n / 2 (n > 1).
6.n = ∑d∣n φ(d),即n的因數(包括1和它自己)的歐拉函數之和等於n
求歐拉函數
1、求單個歐拉函數
int euler(int n) { int ans = n ; for(int i = 2 ; i * i <= n ; i++) { if(n % i == 0) { ans -= ans / i ; // 跟據歐拉函數的通項公式展開一步一步算 while(n % i == 0)//確保i為n的質因數 { n /= i ; } } } if(n > 1) ans -= ans/n ;//最后可能還剩下一個質因數沒有除,例如10的歐拉函數 return ans ; }
2、埃拉托斯特尼篩求歐拉函數
void euler(int n)//求1-n的歐拉函數 { for(int i = 2 ; i <= n ; i++) phi[i] = i ; for(int i = 2 ; i*i <= n ; i++) { if(phi[i] == i) // 表示i為質數 { for(int j = i ; j <= n ; j += i) { phi[j] = phi[j] / i * (i-1) ;//將i的倍數更新 } } } }
歐拉篩求歐拉函數
void euler(int n)//求1-n的歐拉函數 { memset(vis , true , sizeof(vis)); int cnt = 0 ; for(int i = 2 ; i <= n ; i++) { if(vis[i]) { prime[cnt++] = i ; phi[i] = i - 1 ; } for(int j = 0 ; j < cnt && prime[j] * i <= n ; j++) { vis[i*prime[j]] = 0 ; if(i % prime[j] == 0)//保證每一個數都被它最小質因數篩去 { phi[i*prime[j]] = phi[i] * prime[j] ; break ; } else{ phi[i*prime[j]] = phi[i] * phi[prime[j]];//i與prime[j]互質可以根據歐拉函數的積性函數性質求 } } } }
參考博客https://blog.csdn.net/liuzibujian/article/details/81086324