歐拉函數

                                     算法總結算法

 歐拉函數(Euler's totient function函數

 

歐拉函數的定義:spa

    在數論中,對於正整數N,少於或等於N ([1,N]),且與N互質的正整數(包括1)的個數,記做φ(n)。code

     φ函數的值:blog

    φ(x)=x(1-1/p(1))(1-1/p(2))(1-1/p(3))(1-1/p(4))…..(1-1/p(n)) 其中p(1),p(2)…p(n)爲xstring

的全部質因數;x是正整數; φ(1)=1(惟一和1互質的數,且小於等於1)。注意:每種質因數只有一個。it

     例如:io

         φ(10)=10×(1-1/2)×(1-1/5)=4;function

         1 3 7 9模板

         φ(30)=30×(1-1/2)×(1-1/3)×(1-1/5)=8;

         φ(49)=49×(1-1/7)=42;

 

歐拉函數的性質:

(1)   p^k型歐拉函數:

若N是質數p(即N=p), φ(n)= φ(p)=p-p^(k-1)=p-1。

若N是質數p的k次冪(即N=p^k),φ(n)=p^k-p^(k-1)=(p-1)p^(k-1)。

(2)mn型歐拉函數

設n爲正整數,以φ(n)表示不超過n且與n互素的正整數的個數,稱爲n的歐拉函數值。若m,n互質,φ(mn)=(m-1)(n-1)=φ(m)φ(n)。

(3)特殊性質:

若n爲奇數時,φ(2n)=φ(n)。

對於任何兩個互質 的正整數a,n(n>2)有:a^φ(n)=1 mod n (恆等於)此公式即 歐拉定理

當n=p 且 a與素數p互質(即:gcd(a,p)=1)則上式有: a^(p-1)=1 mod n (恆等於)此公式即 費馬小定理

 

歐拉函數相關的證實:

(1)   p^k型的歐拉函數的證實:

對於給定的一個素數p: φ(p)=p-1 那麼容易證實φ(n)=p^k-p^(k-1)

已知少於或等於p^k的正整數的個數爲p^k-1,其中和p^k不互質的正整數有{ p×1,p×2,...,p×(p^(k-1)-1)},共計p^(k-1)-1個

故: φ(n) = p^k-1-(p^(k-1)-1)=p^k-p^(k-1)。

(2)   mn型的歐拉函數的證實:

由於:x=mn m與n互質(即:gcd(m,n)=1);根據中國剩餘定理Z(x)和Z(m)×Z(n)之間存在一一映射,因此x的徹底餘數集(見下面參考)中的元素的個數Z(x)等於Z(m)×Z(n)元素的個數;而Z(m)×Z(n)= φ(m)φ(n)

故有: φ(mn) =φ(m)φ(n) 成立。

(3)任意正整數的歐拉函數的相關證實:

任意一個整數n均可以表示爲其質因子的乘積:

 n=(p(1)*k(1)) *(p(2)*k(2)) *(p(3)*k(3))…(p(i)*k(i))*…*(p(I)*k(I)) 其中I爲n 的質因子的個數。

根據(1)(2)的結論,很容易得出它的歐拉函數爲:

φ(n)=n(1-1/p(1))(1-1/p(2))(1-1/p(3))(1-1/p(4))…..(1-1/p(i)) 其中I爲n 的質因子的個數。

對於任意n>2,2|φ(n) 一定存在 p(i)-1是偶數

 

歐拉定理的相關證實:

(1)  令Z(n)={ X(1),X(2),…,X(φ(n)) }  S={ a*X(1) mod n, a*X(2) mod n ,…,a*X(φ(n)) mod n },則 Z(n)=S。

1)由於a與n互質(即:gcd(a,n)=1), X(i)(1≤i≤φ(n))與n互質(即:gcd(X(i),n)=1);因此

a*X(i)與n互質(即:gcd(a*X(i),n)=1),故 a*X(i) mod n ∈ Z(n)。

     2)若i≠j,那麼 X(i)≠X(j) ,又有a與n互質(即:gcd(a,n)==1),則可得出: a*(X(i)) mod n ≠a*X(j) mod n (消去定律)。

(2)   a^(φ(n))*X(1)*X(2)*X(3)*…*X(φ(n)) mod n

=(a*X(1))*(a*X(2))*(a*X(3))*…*(a*X(φ(n))) mod n

=(a*X(1) mod n)*(a*X(2) mod n)*(a*X(3) mod n)*…*(a*X(φ(n)) mod n) mod n

=X(1)*X(2)*X(3)*…*X(φ(n)) mod n。

對比等式左右兩端,由於X(i)(1≤i≤φ(n))與n互質(即:gcd(X(i),n)==1) ,

故: a^φ(n)=1 mod n (恆等於)成立。

 

費馬小定理的相關證實:

若正整數 a與素數p互質,則有a^(p-1)=1 mod n(恆等於)

因爲φ(p)=p-1 且 a^φ(n)=1 mod n ,又有此處的p==n;

故:a^(p-1)=1 mod n成立。

此定理能夠用來簡化冪的模運算:

例如: 計算 7^222的個位數,其實是求7^222被10除的餘數。

     且7與10互質,φ(10)=1,由歐拉定理知7^4= 1mod 10

     故7^222=(7^4)^55*(7^2)=>(1^55)*(7^2)=>49=>9 mod 10

 

歐拉函數的延伸:

於或等於n的數中,與n互質的數的總和爲:φ(x) * x / 2  (n>1)。

 

相關知識參考:

 

徹底餘數集合:

定義小於 n 且和 n 互質的數構成的集合爲 Z(n) ,稱呼這個集合爲 n 的徹底餘數集合。 顯然 |Z(n)| =φ(n) 。

 

同餘定理:

     若是 a mod b = c 則有(a+kb) mod b =c(k爲非0整數)

     若是 a mod b = c 則有(ka) mod b =kc (k爲正整數)

     (a+b) mod c =((a mod c)+(b mod c )) mod c;

     (a*b) mod c=((a mod c)*(b mod c)) mod c

 

 

 

歐拉函數模板

   (1)直接求小於或等於n,且與n互質的個數:

  int Euler(int n)

{

    int ret=n;

    for(int i=2;i<=sqrt(n);i++)

     if(n%i==0)

      {

        ret=ret/i*(i-1);//先進行除法防止溢出(ret=ret*(1-1/p(i)))

        while(n%i==0)

          n/=i;

     }

    if(n>1)

          ret=ret/n*(n-1);

        return ret;

}

 

篩選模板:求[1,n]之間每一個數的質因數的個數

#define size 1000001

int euler[size];

void Init()

{

     memset(euler,0,sizeof(euler));

          euler[1]=1;

     for(int i=2;i<size;i++)

       if(!euler[i])

       for(int j=i;j<size;j+=i)

       {

              if(!euler[j])

               euler[j]=j;

               euler[j]=euler[j]/i*(i-1);//先進行除法是爲了防止中間數據的溢出

         }

}

代碼:

 1 /*#include<stdio.h>
 2 #include<math.h>
 3 int main(){
 4     int N,ans;
 5     while(~scanf("%d",&N)){
 6             ans=N;
 7         for(int i=2;i<=sqrt(N);i++)
 8             if(N%i==0){
 9                 ans=ans/i*(i-1);
10                 while(N%i==0)N/=i;
11             }
12             if(N>1)ans=ans/N*(N-1);
13        printf("%d\n",ans);
14     }
15     return 0;
16 }
17 */
18 #include<stdio.h>
19 #include<string.h>
20 const int MAXN=1000010;
21 int dp[MAXN];
22 int main(){
23     memset(dp,0,sizeof(dp));
24     dp[1]=1;
25     for(int i=2;i<MAXN;i++){
26         if(dp[i])continue;
27         for(int j=i;j<MAXN;j+=i){
28                 if(!dp[j])dp[j]=j;
29             dp[j]=dp[j]/i*(i-1);
30         }
31     }
32     int N;
33     while(~scanf("%d",&N))printf("%d\n",dp[N]);
34     return 0;
35 }
相關文章
相關標籤/搜索