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

 歐拉定理html

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

證實以下:函數

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

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

  這些數有以下兩個性質:htm

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

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

  那麼由於有 φn 個這樣的數,Xmod n(i=1~φn)因此就有 φn 個不一樣的餘數,而且都是模數天然是(0~n-1)it

 (2)對於任意的aXi(mod n)都與n互質。這不難想,由於an互質這是歐拉函數的條件,Xi(1~n)n互質的數的集合中的元素。因此若是a*Xi作爲分子,n作爲分母,那麼io

他們構成的顯然就是一個最簡分數,也就是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);
    }
} 
相關文章
相關標籤/搜索