1. 程式人生 > >擴展歐幾裏得學習筆記

擴展歐幾裏得學習筆記

擴展歐幾裏得 baby 理解 方程 [] urn 歐幾裏得 amp 求解

擴展歐幾裏得算法用於求解形如

ax+by=gcd(a,b)

的方程(其中a,b是常量且>=0)
首先如果b=0,則顯然有x=1,y=0滿足上方程

然後如果b>0的話:
首先我們知道gcd(a,b)=gcd(b,a%b)(歐幾裏得算法求兩數gcd的原理)
設上面那個方程的通解為x0,y0
所以就有

a×x0+b×y0=gcd(a,b)

那麽

b×x0+(a%b)×y0=gcd(b,a%b)=gcd(a,b)


這裏證明個小結論(神仙都是腦補吧……)
a%b==a-b×[a/b],其中[]表示取整
設a=k×b+m
a%b==m,a/b==k,那麽a-b×[a/b]=a-k×b=m=a%b


然後就有

b×x0+(a%b)×y0=b×x0+(a-b×[a/b])×y0

展開,再整理能得到

a×y0+b×(x0-y0×[a/b])

然後上面一長串式子連等下來可以得到

a×y0+b×(x0-y0×[a/b])=gcd(b,a%b)=gcd(a,b)=ax+by(最後這個=開始的)

觀察等式兩邊得到

x=y0,y=x0-y0×[a/b]

然後就可以根據上面過程開始遞歸了,註意判下邊界(b==0)

從lyd書上抄了個代碼過來覺得好像理解得更透徹了一點……
所以說學習要勤抄代碼(霧
代碼我丟一下

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 z=x;x=y;y=z-y*(a/b);
    return d; 
}

擴展歐幾裏得學習筆記