# 扩展欧几里得算法:
/*
功能:已知a,b
求解满足 ax+by= gcd(a,b) = d
的一组 x,y
*/
由 辗转相除法 得
gcd(a,b) = gcd(b,a%b)
//a%b = a-[a/b]*b []:下取整
#原理:ax+by=d --> bx+(a%b)y = d
// bx' + (a-[a/b]*b)y' = d
// bx' + ay'- [a/b]*by' = d
// ay'+ b(x'-[a/b]*y') = d
x=y'
y=x'-[a/b]*y'
//要先用temp记下x'
int exgcd(int a, int b, int &x, int &y){
if(b==0){
x=1;
y=0;
//疑问:为什么这里y=0?
//y=1也可以,为啥,是不是y等于任何数都OK?
return a;
}
int r = exgcd(b,a%b,x,y);
//不能直接返回!!! 先记下返回值
//由递归得到这一步用来计算的 x',y'
//算得这一步的x,y后 再返回
int temp=x;
x=y;
y=temp - a/b*y;
return r;
}
通过 扩展欧几里得 求得一组特解(X,Y)
那么如何求通解呢?
aX + bY = d 如果将x+k1, y-k2 仍然保持原方程成立
则 x+k1, y-k2就是方程新解
如何求k1, k2 ?
a*(x+k1) + b*(y-k2) = d
a*x + a*k1 + b*y - b*y2 = d
a*x + b*y + a*k1 - b*y2 = d
若要使原方程成立,则 a*k1=b*y2
k1=b,k2=a 显然不能包括所有解
当 a*k1 = b*k2 = t*lcm(a,b)可以保证得到所有解
lcm(a,b)=a*b/gcd(a,b)
k1=b/gcd(a,b)
k2=a/gcd(a,b)
通解:
x = X + b/gcd(a,b)
y = Y - a/gcd(a,b)
对于 ax+by=c
当 c 是 gcd(a,b)倍数 时 方程有解
即 gcd(a,b) * t =c
t= c/gcd(a,b)
x= tX + b/gcd(a,b)
y= tY + a/gcd(a,b)
扩展欧几里得算法
最新推荐文章于 2022-04-05 22:07:44 发布