淺談擴展gcd

淺談擴展gcd

前言

有一段時間覺得擴展gcd很簡單,然後不知道爲什麼有一段時間又覺得迷惑不清,於是現在我來重新梳理一下。

擴展gcd是什麼

ax+by=gcd(a,b)ax+by=gcd(a,b)a,ba,b不完全爲0,且x,yx,y都爲整數解。求解。

注:[][]爲向下取整的意思

求解

假設a>ba>b,
1.b=0gcd(a,b)=a1.顯然當b=0時,gcd(a,b)=a。此時,x=1.y=0x=1.y=0
2.a<>ba<>b
ax1+by1=gcd(a,b)ax1+by1=gcd(a,b)
bx2+(amodb)y2=gcd(b,amodb)bx2+(a mod b)y2=gcd(b,a mod b)
gcd(a,b)=gcd(b,amodb)gcd(a,b) = gcd(b,a mod b)
可知
ax1+by1=bx2+(amodb)y2ax1+by1=bx2+(a mod b)y2
可知
ax1+by1=bx2+(a[a/b]b)y2=ay2+bx2[a/b]by2ax1+ by1= bx2+ (a - [a / b] * b)y2=ay2+ bx2- [a / b] * by2

ax1+by1==ay2+b(x2[a/b]y2)ax1+ by1 == ay2+ b(x2- [a / b] *y2)
易得
x1=y2;y1=x2[a/b]y2x1=y2; y1=x2- [a / b] *y2
則可遞歸求出一組x,yx,y,其他解見求解不定方程

模板

void exGcd(int a,int b,int &x,int &y)
{
    if(b==0)
    {
        x=1;y=0;
        return;
    }
    exGcd(b,a%b,x,y);
    int t=x;x=y;y=t-a/b*y;
}

我們需要的解則就是x,yx,y(該組解沒有什麼其他特點)

應用

……整理到現在我發現擴展gcd好simpl*啊

求乘法逆元

存在同餘方程axb(modn)ax≡b (mod n)
如果gcd(a,n)==1gcd(a,n)==1b==1b==1
ax1(modn)ax≡1 (mod n )
可等同於求方程
ax+ny=1ax+ny=1

過程:

設,xy(modp)x≡y(mod p)
可得:x+kp=yx+kp=y,kk可正可負
相當於說,pp是x的除以的數,yy是餘數,所以可得
那麼把上面的方程代入亦可得解

則用擴歐求之

線性同餘方程(其實和上面差不多)

axb(modn)ax≡b (mod n)
bb%(gcd(a,n)==0)(gcd(a,n)==0),則有解
可轉換爲ax+ny=bax+ny=b
則用擴歐求之

求解不定方程

ax+by=cax+by=c
首先你必須要保證gcd(a,b)gcd(a,b)要整除c,
g=gcd(a,b),a=a/g,b=b/g,c=c/gg=gcd(a,b),a'=a/g,b'=b/g,c'=c/g
由線性同餘方程,我們可以得出ax+by=1a'x'+b'y'=1的整數解(看上面mo)
那麼acx+bcy=ca'c'x'+b'c'y'=c'
然後可得 agcx+bgcy=cga'gc'x'+b'gc'y'=c'g
acx+bcy=cac'x'+bc'y'=c
所以x0=cxx0=c'x'y0=cyy0=c'y'則爲方程的一組解

然後
因爲ax+by=ca'x+b'y=caxc(modb)a'x≡c'(modb')可以互相轉換(線性同餘方程的應用)
所以xx是模bb'同餘的一個剩餘類
可得
x=x0+bt,y=y0attx=x0+b'*t,y=y0-a'*t,t是整數

剩餘類:一個整數被正整數n除後,餘數有n種情形:0,1,2,3,…,n-1,它們彼此對模n不同餘。這表明,每個整數恰與這n個整數中某一個對模n同餘。這樣一來,按模n是否同餘對整數集進行分類,可以將整數集分成n個兩兩不相交的子集。我們把(所有)對模n同餘的整數構成的一個集合叫做模n的一個剩餘類。

加油搞懂它!!!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章