扩展欧几里得
定义
就是如何求得 \(ax + by = d\) 的一个解, \(d = (a, b)\)
做法
考虑使用欧几里得算法的思想, 令 \(a = bq + r\), 其中 \(r = a \bmod b\)
递归求出 \(bx + ry = d\) 的一个解
设求出 \(bx + ry = d\) 的一个解为 \(x = x_0, y = y_0\)
将 \(a = bq + r\) 带入 \(ax + by = d\) 得
\(b(qx + y) + rx = d\)
令 \(qx+y = x_0, x = y_0\), 则上式成立
故 \(x = y_0, y = x_0 - qy_0\) 为 \(ax + by = d\) 的解
递归的边界: \(b = 0\) 时, 令 \(x = 1, y = 0\).
code
void exgcd(int a, int b, int &x, int &y) {
if (b == 0) {
x = 1;
y = 0;
return ;
}
int q = a / b, r = a % b;
exgcd(b, r, y, x);
y -= q * x;
}
求得所有解
先用 \(exgcd\) 求出任意一个解 \(x = x_0, y = y_0\)
再求出 \(ax + by = 0\) 的最小的解
\(x = d_x = \dfrac{b}{(a, b)}, y = d_y = -\dfrac{a}{(a, b)}\)
所有解就是 \(x = x_0 + kd_x, y = y_0 + kd_y, k \in Z\)
证明
我们可以设 \(a > b\)
\((1)\) 当 \(b = 0\), \(gcd(a, b) = 0\). 此时 \(x = 1, y = 0\);
\((2)\) 当 \(ab \neq 0\) 时
设 \(ax + by = gcd(a, b)\);
\(bx_0+( a \bmod b) y_0 = gcd(b, a \bmod b)\)
根据欧几里得算法有 \(gcd(a, b) = gcd(b, a \bmod b)\);
则: \(ax + by = bx_0 + (a \bmod b) y_0\)
即: \(ax + by = bx_0 + (a - \lfloor{\dfrac{a}{b}}\rfloor * b)y_0 = ay_0 + bx_0 - \lfloor{\dfrac{a}{b}}\rfloor*by_0\)
根据恒等定理得: \(x = y_0, y = x_0 - \lfloor{\dfrac{a}{b}}\rfloor * y_0\);
这样我们就得到了求解 \(x,y\) 的方法: \(x.y\) 的值基于 \(x_0,y_0\).