擴展歐幾里得算法 and 乘法逆元


為什么算法成對出現?因為它們確實關系很密切呀。

前置芝士:裴蜀定理

裴蜀定理得名於法國數學家艾蒂安·裴蜀,說明了對任何整數a、b和它們的最大公約數d,關於未知數x和y的線性丟番圖方程(稱為裴蜀等式): ax + by = m 有解當且僅當m是d的倍數。

(大忙人跳過上面的屁話)

一句話說出來就是對於方程: a*x + b*y = m有解,當且僅當 m是gcd(a,b)的整數倍

啊這個證明我不會,因為我菜

 

FAQ:(這玩意跟擴展歐幾里得定理和乘法逆元什么關系啊!!)

A:正當關系

 

那么乘法逆元是什么啊?

 

乘法逆元是醬紫的:對於一組數a,b,求a在模b意義下的逆元相當於求解一個數    使得:

t*a  ≡ 1 (mod b)

然后這個式子可以變形:  t * a = b*k + 1(k是一個正整數)      ------→  t*a - b*k =1

 

這不就是裴蜀定理的形式了嗎?對於這個方程如果要有解,那么1要是gcd(a,b)的倍數咯?

那就意味着gcd(a,b)必須等於1咯?

沒錯!對於a,b如果要使得a在模b的意義下存在逆元的充要條件為:   a與b互質

那么就可以解這個方程了呀,解出這個方程乘法逆元不也就求出來了嗎?

WTF?怎么解呀?眾所周知兩個未知數一個方程,這個方程是有多個解的啊!

沒關系直接來整一個解x0,y0使得 x0*a +y0* b=gcd(a,b)

 

這時候,擴展歐幾里得算法就出來整事情了。(是不是跟gcd有關的都離不開歐幾里得啊QAQ)

 還記得GCD(a,b)中遞歸求解a,b的最大公因數的過程了嗎?

其終止條件:if(b==0)return a;

如果b == 0 的時候,這樣子就意味着我們已經知道了"a,b"的最大公因數是a了

得到一組解是:x = 1 ,y = 0,這時候 a*1 + b*0 = gcd(a,b)(因為此刻a和b都不是初始狀態下的a,b了,此刻a=gcd(a,b),b=0)

這時候遞歸返回這一組解到上一層。

 

因為是遞歸求解gcd,求了a,b的gcd,下一步就是求 b,a%b的gcd,但是其實這里的 a,b的gcd和 b,a%b的gcd其實是相等的(不然我們怎么遞歸求解)

所以假如我們知道了   一組解x1,y1使得  b*x1 + (a%b)   *  y1  =gcd(a,b)

那么x1,y1這組解和x以及y有沒有關系呢?

不妨考慮對:  b*x1 + (a%b)   *  y1  =gcd(a,b)這個式子變形

 

a%b =   a-(a/b)*b  (這里的"/"表示整除,向下取整,例如 5/2 = 2,3/2=1)

 

那么b*x1+(a-(a/b)*b)*y1=gcd

所以b*x1+a*y1-(a/b)*b*y1=gcd

         a*y1+b*(x1-(a/b)*y1)=gcd

所以這里求得:x=y1,y=x1-(a/b)*y1

 

接着就可以遞歸到第一層求得答案了啊!(這也就是為什么擴展歐幾里得能求逆元的原因了!)

 繼續貼上丑陋的代碼:

int exgcd(int a,int b,int &x,int &y){
    if(b == 0){x=1,y=0;return a;}
    int x1,y1;
    int d=exgcd(b,a%b,x1,y1);//記得記錄最大公因數
    x=y1;
    y=x1-a/b*y1;
    return d;
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM