歐幾里得:
int gcd(int a, int b)
{
return !b ? a : gcd(b, a%b);
}
int lcm(int a, int b)//最小公倍數
{
return a / gcd(a, b) * b;//先除後乘避免溢出
}
擴展歐幾里得:
存在整數對
推導過程:
用遞歸求解擴展歐幾里得,設已經求出了下一層遞歸的解,即:
又
將
當
寫成代碼,模板如下
int extgcd(int a, int b, int &x, int &y)
{
int d = a;
if(b != 0)
{
d = extgcd(b, a%b, y, x);
y -= (a / b) * x;
}
else x = 1, y = 0;
return d;
}
求解不定方程:
若
通過上面的方法可得到一組特解
證明:
首先
即
通解爲
在所有解中最小的正整數爲
所以對於方程
注意:若
int cal(int a, int b, int c)
{
int x, y;
int gcd = extgcd(a, b, x, y);
if(c % gcd != 0) return -1;
x *= c/gcd;
b /= gcd;
if(b < 0) b = -b;
int ans = x % b;
if(ans <= 0) ans += b;
return ans;
}
同餘方程:
根據上面的內容,我們可以得到:
解線性方程ax+by=c
bool cal(int a, int b, int c)
{
int x0, y0;
int d = extgcd(a, b, x0, y0);
if(c % d) return false;
int x = x0*c/d, y = y0*c/d;
kx = b/d, ky = -a/d;
return true; // 解集爲:(x+kx*t, y+ky*t),t爲整數
}