数论 —— 欧拉函数
生活随笔
收集整理的這篇文章主要介紹了
数论 —— 欧拉函数
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
【定義】
對正整數 n,歐拉函數是小于等于 n 的數中與 n 互質的數的個數,記作:
例如:,因為 1、3、5、7 均與 8 互質。
【性質】
1)若 n 為一素數 p,則:
2)若 n 為一素數 p 的冪次?,則:
例如:要求?,由于 16=2*2*2*2,故?
3)若 n 為任意兩個互質的數 a、b 的積,則:
例如:要求?,由于 40=5*8,且 5、8 互質,所以?
4)設??為 正整數 n 的素數冪乘積表達式,則:
5)若?,則:
6)若?,則:
7)前 n 個數的歐拉函數的和為:
【求法】
1.一般方法
求一個數 x 的歐拉函數
int Euler(int x) {int res=x;for(int i=2;i<(int)sqrt(x*1.0)+1;i++){if(x%i==0){res=res/i*(i-1);while(x%i==0)/// 保證i一定是素數x/=i;}}if(x>1)res=res/x*(x-1);return res; }2.遞推求法
打表取 1 到 N 的所有歐拉函數并存在數組 phi 中
int phi[N]; void Euler() {for(int i=1;i<=N;i++)phi[i]=i;for(int i=2;i<=N;i+= 2)phi[i]/=2;for(int i=3;i<=N;i+= 2){if(phi[i]==i){for(int j=i;j<=N;j+=i)phi[j]=phi[j]/i*(i-1);}} }3.歐拉函數線性篩法
該算法可在線性時間內篩素數的同時求出所有數的歐拉函數。
如要求一個數的歐拉函數,可以用歐拉函數性質直接求出,但是如果要求前 n 個數的歐拉函數,可采用線性時間的方法篩選歐拉函數值,完成打表。
int phi[N],prime[N]; bool vis[N]; void Euler(int n) { int cnt=0;phi[1]=1;for(int i=2;i<=n;i++){if(!vis[i]) {prime[++cnt]=i;//篩素數的時先判斷i是否是素數 phi[i]=i-1;//當i是素數時phi[i]=i-1 }for(int j=1;j<=cnt;j++){if(i*prime[j]>n)break;vis[i*prime[j]]=1;//確定i*prime[j]不是素數if(i%prime[j]==0)//看prime[j]是否是i的約數 { phi[i*prime[j]]=phi[i]*prime[j];break; } else phi[i*prime[j]]=phi[i]*(prime[j]-1);//其prime[j]-1就是phi[prime[j]],利用了歐拉函數的積性 } } }【例題】?
總結
以上是生活随笔為你收集整理的数论 —— 欧拉函数的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 图论 —— 二分图 —— KM 算法
- 下一篇: 最佳调度问题(SSOJ-2367)