1. 程式人生 > >【結論】【數論】拓展歐幾里得演算法、費馬小定理

【結論】【數論】拓展歐幾里得演算法、費馬小定理

1、歐幾里得原理
(1)歐幾里得演算法

    int gcd(int a,int b) 
{ 
    return b==0?a:gcd(b,a%b); 
} 

(2)、拓展歐幾里得:在已知a、b的情況下,求x*a+b*y=gcd(a,b)的一組整數解
1)、推導:
/* 設 a* x1+b* y1=gcd(a, b), b* x2+(a%b)*y2=gcd(b, a%b);
因為 gcd(a, b)==gcd(b, a%b)
所以 a*x1+b*y1=b*x2+(a%b)*y2  
設 r=a%b, r =a-k* b
則 a* x1+b* y1=b* x2+(a-k* b)*y2   
a* x1+b* y1=b* x2+(a-(a/b)* b)*y2   
a* x1+b* y1=b* x2+a*y2-b*(a/b)*y2  
a* x1+b* y1=a* y2+b* (x2+(a/b)y2)

/
即 x1=y2,y1=x2+a/b*y2

2)、程式碼:

    long long ex_gcd(long long a,long long b,long long &x,long long &y)
{
    if(b==0)
    {
        x=1,y=0;
        return a;
    }
    long long r,y1,x1;
    r=gcd(b,a%b,x1,y1);
    x=y1,y=x1-a/b*y1;
    return r;
}
//當不用判斷a,b是否互質時可寫為:
void ex_gcd(lnog long
a,long long b,long long &x,long long &y) { if(b==0) { x=1;y=0; return; } long long x1,y1; ex_gcd(b,a%b,x1,y1); x=y1;y=x1-a/b*y1; }

(3)、應用
1)、判斷a* x+b*y=c有無整數解:
設 d=gcd(a,b);
if(c%d!=0)無解 else 有解

2)、求a* x+b*y=c通解


設a* x+b*y=d=gcd(a,b)的解為x0、y0
則a* x+b*y=c的解為 x=x0*c/d y=y0*c/d
通解為 x=x0*c/d+k*b/d y=y0*c/d-k*a/d (k為整數)

4)、求乘法逆元
詳見後

2、費馬小定理:若p為質數,且a、p互質,則a^(p-1)≡1(mod p)
應用:求乘法逆元
詳見後

3、乘法逆元:ax≡1(mod n)的最小正整數解稱為a關於模n的乘法逆元。
(1)、存在條件:an-ny=1有解

(2)、求法
1)、拓歐求

    long long inverse(long long a)
{
    long long x,y;
    if(gcd(a,n,x,y)==1) return (x+n)%n;
    return -1;
}

2)、費馬小定理求
設x關於模n的乘法逆元為x0,則(x*x0)≡1(mod n)
又因為x^(t-1)≡1(mod n)
x0=x^(t-2)

(3)、應用:
1)、逆元(a/b)%p==(a*b0)%p
2)、降冪(a^b%p=a^(b%(p-1))%p)