學習筆記----擴充套件歐幾里德

畫船聽雨發表於2014-03-03

原文連線:http://www.cnblogs.com/ka200812/archive/2011/09/02/2164404.html


我個人覺得第一次看到這個程式你會有以上兩個不明白的地方(見註釋),下面我分別解釋
不明處1:由擴充套件歐幾里得定理:ax+by==gcd(a,b)---式1,而此時b==0,也就是說gcd(a,0)==a。原式變為ax+by==a --> x==1,y==0。應該夠清楚了吧
不明處2:這裡先說明一下我的一些規則,x,y表示第一次遞迴時的值,x1,y1表示第二次遞迴時的值。那麼
gcd(a,b)==gcd(b,a%b),同時都代入式1,有ax+by==b*x1+(a%b)*y1。將右邊變形一下
b*x1+(a%b)*y1==b*x1+(a-(a/b)*b)*y1==a*y1+b*(x1-(a/b)*y1),最終得到ax+by==a*y1+b*(x1-(a/b)*y1)
也就是說,上一深度的x等於下一深度的y1,上一深度的y等於下一深度的x1-(a/b)*y1。    需要注意,上面推導時用的除法都是整型除法
到這裡為止,我們便得到了不定式ax+by==gcd(a,b)的一組解,x、y。
那麼對於一般的不定式ax+by==c,它的解應該是什麼呢。很簡單,x1=x*(c/gcd(a,b)),y1=y*(c/gcd(a,b))。很好理解吧~
再深入一點,就解出這麼一組解其實一般來說是解決不了什麼問題的。沒有哪個ACM的題這麼簡單吧。。。比如我們現在要得到所有的解,那麼這所有的解究竟是什麼呢?
直接說吧,假設d=gcd(a,b). 那麼x=x0+b/d*t; y=y0-a/d*t;其中t為任意常整數。
這個是怎麼推匯出來的,說實話我也不知道,就先這麼記著吧!

PS:這裡說一下那個公式為什麼對。已知a*x+b*y = d <==>(a/d)*x+(b/d)*y = 1(1); 設x0,y0.是滿足條件的一組解。將x = x0+b/d*t;y = y0-a/d*t;帶入(1)中得到a/d*x0+t+b/d*y0-t = 1;顯然這是對的啊。

擴充套件歐幾里德模版:

LL exit_gcd(LL a, LL b)
{
    if(b == 0)
    {
        x = 1;
        y = 0;
        return a;
    }
    LL p = exit_gcd(b, a%b);
    LL t = x;
    x = y;
    y = t-(a/b)*y;
    return p;
}



相關文章