gcd&&extend_gcd

一、gcd:

int gcd(int a,int b){return b==0?a:gcd(b,a%b);}

二、extend_gcd:

int extend_gcd(int a,int b,int &x,int &y)
{
    if(b==0){
        x=1;y=0;
        return a;
    }
    else{
        int result=extend_gcd(b,a%b,y,x);
        y-=x*(a/b);
        return result;
    }
}

注:用于求出a,b的最大公约数,且求出x,y满足:ax+by=gcd(a,b)

下面给出相关证明:

1、当b=0时,ax+by=gcd(a,0)=a,所以此时x=1,y=0

2、当b>0时,在欧几里得算法的基础上,已知:

因为:gcd(a,b)=gcd(b,a%b);

           当前状态gcd(a,b)=a*x1+b*y1;

所以:下一状态(即:令a=b,b=a%b):gcd(b,a%b)=b*x2+(a%b)*y2=gcd(a,b);@

因为:a%b=a-(a/b)*b(即:余数=被除数-除数的最大整数倍)

所以上式@可化为:b*x2+(a-(a/b)*b)*y2=gcd(a,b)

进一步化简得:a*y2+b*(x2-(a/b)*y2)=gcd(a,b)

因为最初的状态:gcd(a,b)=a*x1+b*y1:

 递推得到的状态:gcd(a,b)=a*y2+b*(x2-(a/b)*y2)

所以:a*x1+b*y1=a*y2+b*(x2-(a/b)*y2)

两边相比可得:x1=y2

                         y1=x2-(a/b)*y2=x2-(a/b)*x1

完整测试代码:

#include <bits/stdc++.h>
#define int long long
using namespace std;

int gcd(int a,int b){return b==0?a:gcd(b,a%b);}

int extend_gcd(int a,int b,int &x,int &y)
{
    if(b==0){
        x=1;y=0;
        return a;
    }
    else{
        int result=extend_gcd(b,a%b,y,x);
        y-=x*(a/b);
        return result;
    }
}

signed main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    int a,b,x,y;
    cin>>a>>b;
    //int ans=gcd(a,b);
    int ans=extend_gcd(a,b,x,y);
    cout<<ans<<" "<<x<<" "<<y<<endl;
    return 0;
}
发布了89 篇原创文章 · 获赞 5 · 访问量 6706

猜你喜欢

转载自blog.csdn.net/Mr_Kingk/article/details/103448975
gcd