要整擴展歐幾里得,我們肯定要學會歐幾里得算法,如果你沒有學過gcd(a,b)=gcd(b,a%b),那么打開這個鏈接:歐幾里得算法
好了,如果你已經學完了歐幾里得,那么就能默認你知道gcd(a,b)=gcd(b,a%b),那么什么是擴展歐幾里得,就是對於ax+by=gcd(a,b),一定有一組整數解x,y(注意!不要用24和36這個例子卡我,x,y是整數,可以為負的!)
在證明之前,我們需要明確一種術學上的證明工具,數學歸納法:
證明當n= 1時命題成立。
假設n=m時命題成立,那么可以推導出在n=m+1時命題也成立。(m代表任意自然數)
然后命題得證。
而在遞歸式中也是如此。但是會有所不同
當b=0時,很明顯,這個定理時成立的,y取0,x取1,那么等式成立
現在只需要證,假設定理gcd(b,a%b)成立,那么定理在gcd(a,b)中也成立就行。
假設,b*x2+a%b*y2=gcd(b,a%b)時存在解x2,y2
那么,需要證明,a*x1+b*y1=gcd(a,b)存在解x1,y1,
我們令a=k*b+c,也就是c是a%b.
移項得:c=a-k*b.將這個式子代入到需要證明的式子:b*x2+(a-k*b)*y2=gcd(b,a%b),再將其運用乘法分配律:b*x2+a*y2-k*b*y2=gcd(b,a%b)
再合並同類項:a*y2+b*(x2-k*y2)=gcd(b,a%b)=gcd(a,b)
我們只需要讓x=y2,y=(x2-k*y2)不就行了?
得證,然后代碼實現過程也是怎么寫的。
(已知a、b,求一組解x、y使ax+by=gcd(a,b))
#include <iostream> #include <cstdlib> #include <cstring> #include <algorithm> #define REP(i,k,n) for(int i=k;i<=n;i++) #define in(a) a=read() using namespace std; inline int read(){ int x=0,f=1; char ch=getchar(); for(;!isdigit(ch);ch=getchar()) if(ch=='-') f=-1; for(;isdigit(ch);ch=getchar()) x=x*10+ch-'0'; return x*f; } int x,y,t,A,B,d; inline void exgcd(int a,int b,int &x,int &y,int &d){ if(!b) d=a,x=1,y=0; else exgcd(b,a%b,x,y,d),t=x,x=y,y=t-a/b*y; } int main(){ in(A),in(B); exgcd(A,B,x,y,d); cout<<d<<" "<<x<<" "<<y; }
最后,再說一下怎么通過擴展歐幾里得解不定方程ax+by=c.(x、y為整數)
首先,我們必須保證,c能整除gcd(a,b)要不然就無解
然后我們找特解:講a,b除以gcd(a,b),得到a0,b0使他們互質,再用擴展歐幾里得求a0*x+b0*y=1的解x0,y0(這組解是特解)
然后通解就是x=x0+b0*t,y=y0+a0*t。