歐拉函數(Euler_Function)


一、基本概述
在數論,對正整數n,歐拉函數varphi(n)是少於或等於n的數中與n互質的數的數目。此函數以其首名研究者歐拉命名,它又稱為Euler's totient function、φ函數、歐拉商數等。

二、計算公式


三、基本性質
歐拉函數用希臘字母φ表示,φ(N)表示N的歐拉函數.

對φ(N)的值,我們可以通俗地理解為小於N且與N互質的數的個數(包含1).

歐拉函數的一些性質:

1.對於素數p, φ(p)=p-1,對於對兩個素數p,q φ(pq)=pq-1

歐拉函數是積性函數,但不是完全積性函數.

證明:

函數的積性即:若m,n互質,則φ(mn)=φ(m)φ(n).由“m,n互質”可知m,n無公因數,所以φ(m)φ(n)=m(1-1/p1)(1-1/p2)(1-1/p3)…(1-1/pn)·n(1-1/p1')(1-1/p2')(1-1/p3')…(1-1/pn'),其中p1,p2,p3...pn為m的質因數,p1',p2',p3'...pn'為n的質因數,而m,n無公因數,所以p1,p2,p3...pn,p1',p2',p3'...pn'互不相同,所以p1,p2,p3...pn,p1',p2',p3'...pn'均為mn的質因數且為mn質因數的全集,所以φ(mn)=mn(1-1/p1)(1-1/p2)(1-1/p3)…(1-1/pn)(1-1/p1')(1-1/p2')(1-1/p3')…(1-1/pn'),所以φ(mn)=φ(m)φ(n).

即φ(mn)=φ(n)*φ(m)只在(n,m)=1時成立.

2.對於一個正整數N的素數冪分解N=P1^q1*P2^q2*...*Pn^qn.

   φ(N)=N*(1-1/P1)*(1-1/P2)*...*(1-1/Pn).

3.除了N=2,φ(N)都是偶數.

4.設N為正整數,∑φ(d)=N (d|N).

四、求歐拉函數
1、埃拉托斯特尼篩求歐拉函數

觀察歐拉函數的公式, 。我們用phi[x]表示φ(x)。可以一開始把phi[x]賦值為x,然后每次找到它的質因數就(先除再乘,避免溢出)。當然,若只要求一個數的歐拉函數,可以從1到sqrt(n)掃一遍,若gcd(i,n)=1就更新phi[n] phi[n]phi[n]。復雜度為O(logn)(代碼就不給了)。那要求1~n所有數的歐拉函數呢?可以用埃拉托斯特尼篩的思想,每次找到一個質數,就把它的倍數更新掉。這個復雜度雖然不是O(n),但還是挺快的(據說是O(n*ln ln n),關於證明,可以點這里,雖然我看不懂)。
代碼如下:

void euler(int n)
{
    for (int i=1;i<=n;i++) phi[i]=i;
    for (int i=2;i<=n;i++)
    {
        if (phi[i]==i)//這代表i是質數
        {
            for (int j=i;j<=n;j+=i)
            {
                phi[j]=phi[j]/i*(i-1);//把i的倍數更新掉
            }
        }
    }
}
 

 

2、歐拉篩求歐拉函數

前提是要懂歐拉篩。每個數被最小的因子篩掉的同時,再進行判斷。i表示當前做到的這個數,prime[j]表示當前做到的質數,那要被篩掉的合數就是i*prime[j]。若prime[j]在這個合數里只出現一次(i%prime[j]!=0),也就是i和prime[j]互質時,則根據歐拉函數的積性函數的性質,phi[i * prime[j]]=phi[i] * phi[prime[j]]。若prime[j]在這個合數里出現了不止一次(i%prime[j]=0),也就是這個合數的所有質因子都在i里出現過,那么根據公式,復雜度為O(n)。

還是看代碼吧:

void euler(int n)
{
    phi[1]=1;//1要特判 
    for (int i=2;i<=n;i++)
    {
        if (flag[i]==0)//這代表i是質數 
        {
            prime[++num]=i;
            phi[i]=i-1;
        }
        for (int j=1;j<=num&&prime[j]*i<=n;j++)//經典的歐拉篩寫法 
        {
            flag[i*prime[j]]=1;//先把這個合數標記掉 
            if (i%prime[j]==0)
            {
                phi[i*prime[j]]=phi[i]*prime[j];//若prime[j]是i的質因子,則根據計算公式,i已經包括i*prime[j]的所有質因子 
                break;//經典歐拉篩的核心語句,這樣能保證每個數只會被自己最小的因子篩掉一次 
            }
            else phi[i*prime[j]]=phi[i]*phi[prime[j]];//利用了歐拉函數是個積性函數的性質 
        }
    }
}

 


五、例題

http://acm.hdu.edu.cn/showproblem.php?pid=2588

http://poj.org/problem?id=2480

http://acm.hdu.edu.cn/showproblem.php?pid=3501

https://www.luogu.org/problemnew/show/P2158 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM