歐拉-費馬小定理定理(證明及推論)


 歐拉定理

    若正整數 a , n 互質,則  aφ(n)≡1(mod n)   其中 φ(n) 是歐拉函數(1~n) 與 n 互質的數。

證明如下:

    不妨設X1,X2 ...... Xφn1~nn互質的數。

  首先我們先來考慮一些數:aX1,aX2 ...... aXφn

  這些數有如下兩個性質:

 (1)任意兩個數模n余數一定不同:(反證)若存在aX1≡aX2(mod n),則 n |( aX1 - aX,而a,n互質且(X1 - X2)< n,所以n不可能整除( aX1 - aX,也就是說

不存在aX1≡aX2(mod n)。歸納法:對於任意的與n互質的Xi均成立。故得證。

  那么因為有 φn 個這樣的數,Xmod n(i=1~φn)所以就有 φn 個不同的余數,並且都是模數自然是(0~n-1)

 (2)對於任意的aXi(mod n)都與n互質。這不難想,因為an互質這是歐拉函數的條件,Xi(1~n)n互質的數的集合中的元素。所以如果a*Xi做為分子,n做為分母,那么

他們構成的顯然就是一個最簡分數,也就是aXin互質。接下來就可以用歐幾里得算法:因為:gcd(aXi,n)==1所以:gcd(aXi,n)== gcd(n,aXi%n)== 1

 

  這樣,我們把上面兩個性質結合一下來說,aX1(mod n),aX2(mod n) ...... aXφn(mod n)構成了一個集合(性質1證明了所有元素的互異性),並且這些數是1~nn

質的所有數構成的集合(性質1已說明)。這樣,我們巧妙的發現了,集合{ aX1(mod n),aX2(mod n) ...... aXφn(mod n)}經過一定的排序后和集合{ X1,X2 ...... Xφn }

完全一一對應。那么:aX1(mod n)* aX2(mod n)*  ...... * aXφn(mod n)= X1 * X2 * ...... * Xφn   因此:我們可以寫出以下式子:

    aX1 * aX2 *  ...... * aXφn ≡  X* X2 * ...... * Xφn  (mod n),即:(aφn -1)X* X2 * ...... * Xφn ≡ 0 (mod n)

  又因為X* X2 * ...... * Xφnn互質,所以, (aφn -1)| n,那么aφn ≡ 1(mod n)。歐拉定理得證。

 

 費馬小定理:

  對於質數p,任意整數a,均滿足:ap≡a(mod p)

證明如下:

  這個可以用歐拉定理來說明:首先,我們把這個式子做一個簡單變換得:ap-1 * a ≡ a(mod p) 因為a ≡ a(mod p)恆成立,所以ap-1 mod p == 1時費馬小定理才成立,又因為p

質數,所以 φn == n-1 ,所以根據歐拉定理:若a,p互質則ap-1 mod p == 1成立。那么對於a,p不互質,因為p是質數,所以,a一定是倍數a≡ a ≡ 0(mod p)。綜上所述,費馬小定理

成立,其實它算是歐拉定理的一個特例。

 

 歐拉定理的推論:

  若正整數a,n互質,那么對於任意正整數b,有ab≡ab mod φ(n)(mod n)

證明如下:(類似費馬小定理的證明)

  把目標式做一簡單變形:ab - b mod φ(n)* ab mod φ(n)≡ ab mod φ(n)(mod n),所以接下來只需要證明ab - b mod φ(n)≡ 1 (mod n)又因為:

( b - b mod φ(n))| φ(n),不妨設:( b - b mod φ(n))= q*φ(n)q為自然數),則有aq*φ(n)== (aqφ(n),因為a,n互質,那么(aqn也互質,

那么就轉換到了歐拉定理:(aqφ(n)≡ 1 (mod n),成立。所以我們這個推論成立。

 

這個推論可以幫助我們在求冪運算的時候縮小數據范圍和計算次數。具體的說:在求乘方運算時,可以先把底數對mod取模,再把指數對b mod φ(n)取模。

特別的,如果a,mod不互質,且b>φ(n)時,ab≡ab mod φ(n)+ φ(n)(mod n)

 

 

下面我們就用這個推論來做一道題:// http://www.nyzoj.com:5283/problem/6

 

題目:
  給定a,n求出 S=((((aa)a)a)a)a (mod 998244353)
na

輸入:

  輸入僅一行. 兩個正整數an

輸出:

  輸出僅一行. 一個正整數S

 

樣例解釋:

 

  ((22)2)2 mod 998244353 256

數據范圍:

  a,n <= 1018

 

思路:

  先求出指數,即an-1(快速冪求解),並將指數對mod-1(因為mod是質數,那么φ(mod)= mod-1),再用更新后的指數做為新的指數用快速冪求解即可。代碼如下:

#include<cstdio>
typedef long long ll;
ll a,n;
const int M=998244353;
ll mi(ll a,ll b,int mod)
{
    ll re=1; a%=mod;
    while (b)
    {
        if (b&1) re=(re*a)%mod;
        a=(a*a)%mod;
        b>>=1; 
    }
    return re;
}
int main()
{
    scanf ("%lld%lld",&a,&n);
    ll t=mi(a,n-1,M-1);
    printf("%lld",mi(a,t,M));
    return 0;
} 

 

 

課后例題://poj 3696

  給定一個正整數L,L <= 2*109. 問多少個8連在一起的數是L的倍數。如果不存在就輸出0.

//這里省略輸入輸出規則,請讀者自行注意

 

思路:

  x8連在一起可以寫成8*(10x-1)*9,假設d=gcd(L,8)。那么題目可以表達為:L | 8*(10x-1)*9 , 接下來我們做一些簡單的式子變形:

      L | 8*(10x-1)/9  ←→  L*9 | 8*(10x-1) ←→  9L/d | (10x-1) ←→  10x ≡ 1 (mod 9L/d)

引理對於任意互質的正整數a,n滿足:ax≡1(mod n)最小的整數值 X0 φ(n)的約數。

證明如下:

  (反證法)假設X0不是φ(n)的約數,則φ(n)可以表示為:qX0 + r(0 <= r < X0)。題設有:aX0≡1(mod n),那么,aqX0≡1(mod n)且正整數a,n互質,所以有歐拉定理:

 aφ(n)≡1(mod n),即aqX* ar≡1(mod n),繼而得出:ar≡1(mod n),此時r<X0,這與X0是最小的整數值矛盾,所以假設不成立。得證。

所以,接下來我們只需要求出φ(9L/d)並將其約數帶入10x ≡ 1 (mod 9L/d)驗證是否成立即可。求歐拉函數和快速冪,時間復雜度為:O(√(n) * log2 n)。代碼如下:

 

#include<cstdio>
#include<algorithm>
using namespace std;
typedef long long ll;
ll n,mod;
int Case;
ll gcd(ll a,ll b)
{
    return a%b==0 ? b : gcd(b,a%b);
}
ll Er(ll x)
{
    ll re=x;
    for (ll i=2;i*i<=x;i++)
    {
        if (x%i==0)
        {
            re=re/i*(i-1);
            while (x%i==0) x/=i;
        }
    }
    if (x>1) re=re/x*(x-1);
    return re;
}
ll mul(ll a,ll b,ll p)
{
    ll re=0;
    while (b)
    {
        if (b&1) re=(re+a)%p;
        a=2*a%p;
        b>>=1;
    }
    return re;
}
ll ksm(ll a,ll b,ll p)
{
    ll re=1; a%=p;
    while (b)
    {
        if (b&1) re=mul(re,a,p);
        a=mul(a,a,p); b>>=1;
    }
    return re;
}
int main()
{
    while (scanf ("%lld",&n))
    {
        if (n==0) return 0;
        Case++;
        ll d=gcd(n,8);
        ll phi=Er(9*n/d);
        mod=9*n/d;
        ll flag=9223372036854775806;
        for (ll i=1;i*i<=phi;i++)
        {
            if (phi%i==0)
            {
                if (ksm(10,i,mod)==1) 
                  flag=min(flag,i);
                if (ksm(10,phi/i,mod)==1)
                  flag=min(flag,phi/i);
            }
        }
        flag==9223372036854775806?printf("Case %d: 0\n",Case):printf("Case %d: %lld\n",Case,flag);
    }
} 

 


免責聲明!

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



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