贝祖定理 如果 (a,b) 是整数,那么一定存在整数 (x,y) 使得 (ax+by=gcd(a,b)) 。
判断有解性 如果 (ax+by=m) 有解,那么 (m) 一定是 (gcd(a,b)) 的若干倍。如果 (ax+by=1) 有解,那么 (gcd(a,b)=1) 。
辗转相除法求 (gcd)
int gcd(int a, int b){
return b == 0 ? a : gcd(b, a % b);
}
扩展欧几里得求解
对于方程 (ax+by=gcd(a,b)) ,我们有:
[egin{split}
ax_1+by_1 &= gcd(a,b) \
bx_2+(a\%b)y_2 &= gcd(b,a\%b)
end{split}]
两式均满足贝祖定理,且一定存在解。
我们将 ((a\%b)) 换成 ((a - lfloor frac{a}{b} floor cdot b)) 有:
[bx_2+(a - lfloor frac{a}{b}
floor cdot b)y_2 = gcd(b,a\%b)
]
由于 (gcd(a,b)=gcd(b,a\%b)) ,联立两式得:
[egin{split}
x_1 &= y_2 \
y_1 &= x_2 - lfloor frac{a}{b}
floorcdot y_2
end{split}]
易得,边界条件为:
[gcd(a,0)=a \
ax_0+by_0=a Rightarrow x_0 =1;y_0=0
]
扩展欧几里得的通解
设 (x_c,y_c) 为算法求出的一组解,那么方程的通解为:
[egin{split}
x &= x_c + k cdot frac{b}{gcd(a,b)} \
y &= y_c - k cdot frac{a}{gcd(a,b)}
end{split}]
#include<iostream>
#include<cstdio>
#include<cmath>
using namespace std;
int exgcd(int a,int b,int &x,int &y)
{
if(b == 0){
x = 1; y = 0;
return a;
}
int r = exgcd(b, a % b, x, y);
int temp = y;
y = x - (a / b) * y;
x = temp;
return r;
}
int main()
{
int a, b;
cin >> a >> b;
int x, y;
int d = exgcd(a, b, x, y);
cout << x << " " << y << " " << d << endl;
return 0;
}