1. 程式人生 > >歐拉函數 + 線性求法

歐拉函數 + 線性求法

span pan euler strong 直接 推出 ron 出現 nump

歐拉函數:

在數論,對正整數n,歐拉函數是小於n的正整數中與n互質的數的數目(φ(1)=1)。此函數以其首名研究者歐拉命名(Euler‘so totient function),它又稱為Euler‘s totient function、φ函數、歐拉商數等。 例如φ(8)=4,因為1,3,5,7均和8互質。

求法:

①基本公式:φ(n)=n×Π(p|n且p為質數)(1-1/p)

證明: 對於因子p,n以內所有p的倍數的數有n/p個。

利用容斥,有因子p1,p2時,n以內互質的數的個數是:n-n/p1-n/p2+n/(p1×p2)=n(1-1/p1-1/p2+1/(p1×p2)=n(1-1/p1)(1-1/p2)

以此類推可以推出公式。 利用質因數分解可以n^1/2求出來

②性質:

1.若a為質數,φ[a]=a-1;

證明顯然

2.若a為質數,a mod b=0,φ[a×b]=φ[b]×a

證明: 因為所有a的因子都是b的因子,所以在φ[b]基礎上乘a即可。(考慮公式)

3.若a,b互質,φ[a×b]=φ[a]×φ[b] (當a為質數時,if b mod !=0 ,φ[a×b]=φ[a]×φ[b])

證明:a的質因子和b的質因子沒有相同的,而ab的質因子必然在a、b中出現過,所以直接相乘就可以,(考慮公式)

線性求euler

int m[n],phi[n],p[n],nump;
//m[i]標記i是否為素數,0為素數,1不為素數;p是存放素數的數組;nump是當前素數個數;phi[i]為歐拉函數
int make() { phi[1]=1; for (int i=2;i<=n;i++) { if (!m[i])//i為素數 { p[++nump]=i;//將i加入素數數組p中 phi[i]=i-1;//因為i是素數,由特性得知 } for (int j=1;j<=nump&&p[j]*i<n;j++) //用當前已的到的素數數組p篩,篩去p[j]*i { m[p[j]
*i]=1;//可以確定i*p[j]不是素數 if (i%p[j]==0) //看p[j]是否是i的約數,因為素數p[j],等於判斷i和p[j]是否互質 { phi[p[j]*i]=phi[i]*p[j]; //性質2 break; } else phi[p[j]*i]=phi[i]*(p[j]-1); //互質,性質3,其中p[j]-1就是phi[p[j]] } } }

歐拉函數 + 線性求法