淺談擴展gcd
前言
有一段時間覺得擴展gcd很簡單,然後不知道爲什麼有一段時間又覺得迷惑不清,於是現在我來重新梳理一下。
擴展gcd是什麼
ax+by=gcd(a,b),a,b不完全爲0,且x,y都爲整數解。求解。
注:[]爲向下取整的意思
求解
假設a>b,
1.顯然當b=0時,gcd(a,b)=a。此時,x=1.y=0
2.a<>b
設ax1+by1=gcd(a,b)
設bx2+(amodb)y2=gcd(b,amodb)
由gcd(a,b)=gcd(b,amodb)
可知
ax1+by1=bx2+(amodb)y2
可知
ax1+by1=bx2+(a−[a/b]∗b)y2=ay2+bx2−[a/b]∗by2
得
ax1+by1==ay2+b(x2−[a/b]∗y2)
易得
x1=y2;y1=x2−[a/b]∗y2
則可遞歸求出一組x,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,y(該組解沒有什麼其他特點)
應用
……整理到現在我發現擴展gcd好simpl*啊
求乘法逆元
存在同餘方程ax≡b(modn)
如果gcd(a,n)==1且b==1時
ax≡1(modn)
可等同於求方程
ax+ny=1
過程:
設,x≡y(modp)
可得:x+kp=y,k可正可負
相當於說,p是x的除以的數,y是餘數,所以可得
那麼把上面的方程代入亦可得解
則用擴歐求之
線性同餘方程(其實和上面差不多)
ax≡b(modn)
當b%(gcd(a,n)==0),則有解
可轉換爲ax+ny=b
則用擴歐求之
求解不定方程
ax+by=c
首先你必須要保證gcd(a,b)要整除c,
設g=gcd(a,b),a′=a/g,b′=b/g,c′=c/g
由線性同餘方程,我們可以得出a′x′+b′y′=1的整數解(看上面mo)
那麼a′c′x′+b′c′y′=c′
然後可得 a′gc′x′+b′gc′y′=c′g
即ac′x′+bc′y′=c
所以x0=c′x′ , y0=c′y′則爲方程的一組解
然後
因爲a′x+b′y=c和a′x≡c′(modb′)可以互相轉換(線性同餘方程的應用)
所以x是模b′同餘的一個剩餘類
可得
x=x0+b′∗t,y=y0−a′∗t,t是整數
剩餘類:一個整數被正整數n除後,餘數有n種情形:0,1,2,3,…,n-1,它們彼此對模n不同餘。這表明,每個整數恰與這n個整數中某一個對模n同餘。這樣一來,按模n是否同餘對整數集進行分類,可以將整數集分成n個兩兩不相交的子集。我們把(所有)對模n同餘的整數構成的一個集合叫做模n的一個剩餘類。
加油搞懂它!!!