欧几里得算法
又叫辗转相除法
int gcd(int a,int b){
return !b?a:gcd(b,a);
}
ax+by=gcd(a,b)求解
使用拓展欧几里得算法
int extgcd(int a,int b,int &x,int &y){
int temp=a;
if(!b){
x=1,y=0;
}
else{
temp=extgcd(b,a%b,y,x);
y-=(a/b)*x;
}
return temp;
}
然后通过以下式子获得所有解:
x' = x + ( b/gcd) * K
y' = y - (a/gcd) * K
其中K是任意整数
即x和y的所有解分别以b/gcd
和a/gcd
为周期
其中x的最小非负整数解是(x % b/gcd +b/gcd )% (b/gcd),注意b要先取绝对值,推导见算法笔记,但是算法笔记有个错误,就是b也要取绝对值,否则如果b为负数,最小非负x求出来可能为负数
这里实际求x最小非负整数解的时候不用这么麻烦,用一个while循环不断试探,如果x大于0,每轮减去T=|b/gcd|,如果x<0,每轮加上T就行。
当gcd==1时,全部解化简为以下公式
x' = x + b * K
y' = y - a * K
x的最小非负整数解也可以化简为(x%b+b)%b,注意b要先取绝对值
补充:贝祖定理:给定两个整数a、b,必定存在整数x、y使得 ax + by = gcd(a, b),且存在x < b, y < a满足等式。
- 后边黑体字很重要,给出了有解的范围。