扩展欧几里得算法(含严谨证实)

要整扩展欧几里得,咱们确定要学会欧几里得算法,若是你没有学过gcd(a,b)=gcd(b,a%b),那么打开这个连接:欧几里得算法html

好了,若是你已经学完了欧几里得,那么就能默认你知道gcd(a,b)=gcd(b,a%b),那么什么是扩展欧几里得,就是对于ax+by=gcd(a,b),必定有一组整数解x,y(注意!不要用24和36这个例子卡我,x,y是整数,能够为负的!)ios

在证实以前,咱们须要明确一种术学上的证实工具,数学概括法:git

    最简单和常见的数学概括法是证实当 n等于任意一个天然数时某命题成立。证实分下面两步:

    证实当n= 1时命题成立。算法

    假设n=m时命题成立,那么能够推导出在n=m+1时命题也成立。(m表明任意天然数)工具

    而后命题得证。spa

    而在递归式中也是如此。可是会有所不一样code

当b=0时,很明显,这个定理时成立的,y取0,x取1,那么等式成立htm

如今只须要证,假设定理gcd(b,a%b)成立,那么定理在gcd(a,b)中也成立就行。blog

假设,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。

相关文章
相关标签/搜索