一、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;
}