【總結】理解歐幾里德及擴充套件歐幾里德演算法

CN_swords發表於2017-07-24

歐幾里德演算法又稱輾轉相除法,用於計算兩個整數a,b的最大公約數。


gcd(a,b)由遞推所得,自然需要初始值和遞推式。

1. a = b ,  b = a%b 這個遞推式由公理 gcd(a,b)=gcd(b,a mod b) 所得。

證明:gcd(a,b)=gcd(b,a%b)
(a>b)設a = k*b + c, 則 a % b = c; (設 d為a,b的公約數), 則 a/d,b/d都為整數;因為 c = a – k*b,則c/d = a/d – k*b/d,所以c/d 一定為整數 ,得到 d為b,a%b的公約數或為a,a%b的公約數。那麼a,b的所有公約數即為b,a%b的公約數,所以 gcd(a,b)=gcd(b,a%b)

2. 初始值:b = 0 時 ,最大公約數為a。

證明:根據遞推式,往上推一步,gcd(a,b) = gcd(b,a%b),則a % b = 0
當a % b = 0時,其最大公約數即為b。因為a是b的倍數時,自然b為最大公約數。

int gcd(int a,int b){
    if(!b)  return a;
    else    return gcd(b,a%b);
}

擴充套件歐幾里得演算法,求不定方程。

對於不定方程ax+by=c,求滿足其方程的整數解。
擴充套件歐幾里得能對ax+by=gcd(a,b)計算所有x,y的解,只有滿足c%gcd(a,b)==0時,ax+by=c才有解,當然解由ax+by=gcd(a,b)計算結果 * (c/gcd(a,b))得到。
遞推式原理:對於不定方程有:  ax1+by1 = gcd(a,b) ;  也可以替換未知數  bx2+(a%b)y2 = gcd(b,a%b);  由歐幾里得所證的定理 gcd(a,b) = gcd(b,a%b);  那麼ax1+by1 = bx2+(a%b)y2;  將a%b = a-a/b*b,  那麼ax1+by1 = ay2+b(x2-a/b*y) , 有恆等式 x1 = y2 ;  y1 = x2-a/b*y。
得到遞推的等式,我們需要知道其初始點。當b=0時,gcd(a,b)=a,此時x=1,y=0。

計算得到ax+by=c的解,只是ax+by=c的其中的一個解,而其他值滿足:
x(i) = x + b/Gcd(a, b) * t
y(i) = y - a/Gcd(a, b) * t             (其中t為任意整數,兩者需同時進行)
【ps.可以自行代入a,b驗證】

int ExGCD(int a, int b, int& x, int& y)
{
    if(b == 0)
    {
        x = 1, y = 0;
        return a;
    }
    int d = ExGCD(b, a%b, x, y);
    int temp = x;
    x = y;
    y = temp - a/b*y;
    return d;
}

//d為gcd(a,b), x , y得到的是c = gcd(a, b)時的值。

擴充套件歐幾里得演算法,求同餘方程。
同餘方程 ax≡b (mod n)對於未知數 x 求解。
其實求解方程 ax≡b (mod n) 就相當於求解方程 ax+ ny= b, (x, y為整數)

在求解除法取模問題(a/b)%m時,我們可以使用逆元將除法轉換為乘法:假設b存在乘法逆元,即與m互質(充要條件)。設c是b的逆元,b*c ≡ 1(%n),那麼(a/b)%mod = (a/b)*1%mod = (a/b*b*c)%mod = (a*c)%mod。
1. 擴充套件歐幾里得演算法,求模的逆元就相當於ax+ny = 1,要保證x為正整數。
2. 當p為質數時候用費馬小定理x^(p-1)≡1(%p),x*x^p-2≡1(%p),x^p-2為逆元。快速冪求逆元。
3. 當p為質數,線性求逆元。i^(-1) ≡ 1(%p) , 設 p = ka+b,則 ka+b ≡ 0(%p),兩邊同乘a^(-1)b^(-1),則
a^(-1) ≡ -k*b^(-1) (%p),則 a^(-1) = (-p/a * (p%a)^(-1)) (%p)。

也就是說a對p的逆元可以由(p%a)對p的逆元推出。如下:

//一個快速求乘法逆元的模版。。。
inv[0]=0,inv[1]=1;
for(int i=2;i<=N+10;i++)
{
    inv[i]=inv[mod%i]*(mod-mod/i)%mod;
    // i是代表x,mod%i是代表a;
}


相關文章