再习拓展欧几里得算法
我们不妨先来复习一下欧几里得辗转相除法是怎么求两个数的最大公约数的
求 4453 和 5767 的最大公约数时,可作如下除法.
5767÷4453=1 余 1314
4453÷1314=3 余 511
1314÷511 =2 余 292
511 ÷292 =1 余 219
292 ÷219 =1 余 73
219÷73=3 于是得知,5767 和 4453 的最大公约数是 73。
证明:
设x,y的一个公约数是p,设b=x mod y;
再设x=ky+b;
因为 p | x,y;
又因为b=x-ky;
所以可以看出,p | b;所以p也是y,b的公约数。
还可以反证,假设p是y,b的公约数。
则有,p | y,p | x-ky(k是整数)
进而,p | x。
因此(a,b)和(b,a mod b)的公约数是一样的,其最大公约数也必然相等,得证。
代码实现
int gcd(int a,int b)
{
if(a==0) return b;
return gcd(b,a%b);
}
拓展欧几里得:对于不完全为0的非负整数a,b,若gcd(a,b)表示a和b的最大公约数,则必然存在整数对(x,y),是的gcd(a,b)=ax+by
证明:
当b=0,此时gcd(a,b)=a,则x=1,y=0;
当a>b>0
设gcd(a,b)=ax1+by1;gcd(b,a mod b)=bx2+(a mod b)*y
由欧几里得辗转相除法可知,
ax1+by1=bx2+(a-b*[a/b])*y2
合并同类项,得到方程右边化简为ay2+b(x2-[a/b]*y2)
由等式守恒可知,x1=y2,y1=x2-[a/b]*y2
代码实现:
inline int gcd(int a,int b,int &x,int &y)
{
if(b==0)
{
x=1;
y=0;
return a;
}
int r=gcd(b,a%b,x,y);
int temp=x;
x=y; //x1=y2
y=temp-a/b*y; //y1=x2-[a/b]*y2
return r;
}
你当前这一层所用到的x2,y2就是上一层递归,即gcd(b,a%b)这一层的x1,y1。
明天补上exgcd的应用,快困死了
QQ40523591~欢迎一起学习交流~