首先我们先证明一下欧几里得算法。
int gcd(int a,int b)
{
if(b==0)
return a;
else
gcd(b,a%b);
}
可以看出这段求最大公约数的程序是以 gcd(a,b)==gcd(b,a%b) 为前提的,那么我们只要证明出这个前提正确,自然而然就可以证明程序的正确性!!
证明: a=b*p+q (q=a%b) ,所以,gcd(b,q)也就是gcd(b,a%b)既可以整除a,也可以整除b,自然也可以整除gcd(a,b)!
同理,q=a-b*p,gcd(a,b)既可以整除b,也可以整除q,因此gcd(a,b)可以整除gcd(b,q)。
最后由gcd(a,b)|gcd(b,q)和gcd(b,q)|gcd(a,b)两个式子推出gcd(a,b)==gcd(b,a%b)!(a|b表示a可以整除b)
下面再来看看拓展欧几里得算法
拓展欧几里得算法是用来求等式ax+by=gcd(a,b)的一组x,y的解的,这组解有个特点就是|x+y|最小,还有一点需要注意的是如果ax+by=d,并且d!=gcd(a,b)那么方程一定无解。
#include<cstdio>
using namespace std;
#define ll long long
ll x,y;
void extend_gcd(ll a,ll b){
if(!b) {x=1;y=0;}
else{
extend_gcd(b,a%b);
ll t=x;
x=y;
y=t-((ll)(a/b))*y;
}
}
int main(){
ll a,b;
scanf("%lld%lld",&a,&b);
extend_gcd(a,b);
printf("%lld %lld\n",x,y);
return 0;
}
上面这段程序就是拓展欧几里得算法的实现了。
假设我们已经求出了bx'+(a%b)y'=gcd(a,b)的一组解了,那么我们如何根据x',y’来求出x,y呢?
我们知道a%b=a-(a/b)*b,那么上一行中的式子我们是不是可以表示成bx'+(a-(a/b)*b)*y'=gcd(a,b),进一步整理我们就可以得到如下式子:
ay'+b(x'-(a/b)*y')=gcd(a,b)
也就是说 x=y',y=(x'-a/b*y'),上述程序的正确性也就因此得证!!
刚学完拓展欧几里得写个博客加深一下印象,如果能帮助到别人那就更好了。