1. 程式人生 > >歐幾里得 & 拓展歐幾里得演算法 講解 (Euclid & Extend- Euclid Algorithm)

歐幾里得 & 拓展歐幾里得演算法 講解 (Euclid & Extend- Euclid Algorithm)

歐幾里得& 拓展歐幾里得(Euclid & Extend-Euclid)

歐幾里得演算法(Euclid)

背景

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

程式碼:

遞推的程式碼是相當的簡潔:

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


分析:

方法說了是輾轉相除法,自然沒有什麼好介紹的了。。

Fresh肯定會覺得這樣遞迴下去會不會爆棧?實際上在這裡是不會爆棧的,因為遞迴的層數是非常小的,不信你可以隨便拿一些大數測試一下,lrj的白書和紫書上講到gcd函式的遞迴層數不超過40785lgN + 1.6723,其中N=max{a,b}。讓gcd函式遞迴層數最多的是gcd(F(n),F(n-1)),F(n)是Fibonacci數!!至於為什麼博主沒有證明,有想法的小夥伴麻煩在評論在說下下,(*^__^*) 嘻嘻……

拓展歐幾里得(Extend- Euclid)

背景:

擴充套件歐幾里德演算法是用來在已知a, b求解一組x,y [x,y都是整數],使它們滿足貝祖等式: ax+by = gcd(a, b) =d

(解一定存在,根據數論中的相關定理)。擴充套件歐幾里德常用在求解模線性方程及方程組中。                                                                                                                                                                                                                      ——百度百科

用到的幾個歐幾里得重要結論:

1)            gcd(a,b) =  gcd(b,a %b);

2)            gcd(a,0) =  a.

程式碼:

typedef __int64 ll;
void exgcd(ll a, ll b, ll& d, ll& x, ll &y)
{
    if(!b)
    {
        d = a, x = 1, y = 0;
    }
    else
    {
        exgcd(b, a % b, d, y, x);
        y -= x * (a / b);
    }
}


分析:

設如下兩個方程:

ax+by  =  gcd(a,b)  =  d;

bx’+(a%b)y’  =  gcd(b,a%b);

那麼由重要結論(1)有gcd(a,b)  =  gcd(b,a %b),

那麼ax+by  =  bx’+(a%b)y’  =  bx’ +(a – [a/b]*b)y’  =  ay’ + b(x’ – [a/b]y’),

恆等關係有 x = y’ , y = (x’ – [a/b]y’),[a/b]表示a/b的值向下取整。

........

那麼現在就可以用exgcd(a,b,d,x,y)表示方程ax+by = d,那麼由上面一直遞迴下去,直到 b = 0,遞迴結束,此時  d = gcd(a,0) =a , x = 1,y =0;【因為 ax+0*y = gcd(a,0)嘛~】

拓展歐幾里得的幾個應用

求解不定方程

例如:求解不定整數方程ax+by = c

求ax+by = c, 令d =gcd(a,b);

那麼(a / d ) * x + (b / d )* y = c / d

因為(a / d )、(b / d ) 、x、y都是整數,那麼保證原不定整數方程ax+by = c有解的充要條件就是c / d為整數,即cgcd(a,b)的倍數。

如果有解,那麼令 K = c/d;

那麼,對方程aX+bY = d;假設有拓展歐幾里得求出一組解為(X0,Y0),那麼aX0+bY0 = d;等式兩邊同時乘以K,即K*( aX0+bY0 ) = d*K = c;由恆等關係,原方程的解(x0,y0):

 X0 = KX0 = c/d * X0y0 = KY0 = c/d *Y0

不定方程的通解

       若(x0,y0)是不定整數方程ax+by = c的一組解,則他的任意整數解都可以表示成(x0+ kb’, y0-ka’),其中a’ = a/gcd(a,b), b’ = b/gcd(a,b).

例題:

求解模線性方程

方法跟上面類似,將同餘方程轉化為常規線性方程就可以了,跟上面一樣,談到同餘方程的一個解時,其實指的是一個同餘等價類....

具體內容待補充...

求模的逆元

待補充…