扩展欧几里得
概念
扩展欧几里得算法(\(\texttt{exgcd}\)) 是一种可以求出关于 \(x, y\) 的方程 \(ax + by = \gcd(a, b)\) 的通解的算法。
不妨设 \(a > b\),则 \(\tt exgcd\) 的时间复杂度为 \(O(logb)\)
思想
\(\texttt{exgcd}\) 的实现求出的是原方程的一组整数特解 \(x, y.\)
显然当 \(b = 0\) 时原方程有一组特解 \(x = 1, y = 0\)
当 \(b \neq 0\) 时,设方程 \(bx + (a \bmod b)y = \gcd(b, a \bmod b)\) 有一组整数特解 \(x_2, y_2\),则方程 \(ax + by = \gcd(a, b)\) 有一组整数特解为 \(x_1 = y_2, y_1 = x_2 - \lfloor \frac{a}{b} \rfloor y_2\)
递归求解即可。
证明
根据裴蜀定理,存在 \(x, y \in \mathbb{Z}\) 使得 \(ax + by = \gcd(a, b)\)
当 \(b = 0\) 时原方程显然有特解 \(x = 1, y = 0\)
当 \(b \neq 0\) 时,设原方程有一组整数特解 \(x_1, y_1\)
则 \(ax_1 + by_1 = \gcd(a, b) = gcd(b, a \bmod b)\)
设 \(bx_2 + (a \bmod b)y_2 = \gcd(b, a \bmod b)\)
则 \(ax_1 + by_1 = bx_2 + (a \bmod b)y_2\)
又因为 \(a \bmod b = a - \lfloor \frac{a}{b} \rfloor b\)
代入得 \(ax_1 + by_1 = bx_2 + (a - \lfloor \frac{a}{b} \rfloor b)y_2\)
\(ax_1 + by_1 = bx_2 + ay_2 - \lfloor \frac{a}{b} \rfloor by_2\)
\(ax_1 + by_1 = ay_2 + (bx_2 - \lfloor \frac{a}{b} \rfloor by_2)\)
所以有 \(ax_1 + by_1 = ay_2 + b(x_2 - \lfloor \frac{a}{b} \rfloor y_2)\)
易得 \(x_1 = y_2, y_1 = x_2 - \lfloor \frac{a}{b} \rfloor y_2\)
拓展
通解和最小非负整数解
设方程 \(ax + by = \gcd(a, b)\) 有一组整数特解 \(x^{\prime}, y^{\prime}\)
则 \(ax + by = \gcd(a, b)\ (1)\) 且 \(ax^{\prime} + by^{\prime} = \gcd(a, b)\ (2)\)
\((1) - (2)\) 得 \((ax + by) - (ax^{\prime} + by^{\prime}) = 0\)
整理得 \(a(x - x^{\prime}) + b(y - y^{\prime}) = 0\)
即 \(a(x - x^{\prime}) = b(y^{\prime} - y)\)
两边同除 \(\gcd(a, b)\) 得 \(\frac{a}{\gcd(a, b)}(x - x^{\prime}) = \frac{b}{\gcd(a, b)}(y^{\prime} - y)\)
\(\because\) \(\frac{a}{\gcd(a, b)}\) 和 \(\frac{b}{\gcd(a, b)}\) 互质
\(\therefore\) \(x - x^{\prime} = t\frac{b}{\gcd(a, b)}, y^{\prime} - y = t\frac{a}{\gcd(a, b)}, t \in \mathbb{Z}\)
\(\therefore\) 原方程的通解为 \(x = x^{\prime} + t\frac{b}{\gcd(a, b)}, y = y^{\prime} - t\frac{a}{\gcd(a, b)}, t \in \mathbb{Z}\)
\(\therefore\) 原方程的最小非负整数解为 \(x = (x^{\prime} \bmod \frac{b}{\gcd(a, b)} + \frac{b}{\gcd(a, b)}) \bmod \frac{b}{\gcd(a, b)}\)
\(ax + by = c\)
根据裴蜀定理知,原方程有解,当且仅当 \(\gcd(a, b) \mid c\)
先求出 \(ax + by = \gcd(a, b)\) 的一组通解 \(x_0, y_0\)
原式两边乘 \(\frac{c}{\gcd(a, b)}\) 得 \(ax_0\frac{c}{\gcd(a, b)} + by_0\frac{c}{\gcd(a, b)} = c\)
易得原方程的一组特解为 \(x^{\prime} = x_0\frac{c}{\gcd(a, b)}, y^{\prime} = y_0\frac{c}{\gcd(a, b)}\)
类似地,可以得出原方程的通解形式为
\(x = x_0\frac{c}{\gcd(a, b)} + t\frac{b}{\gcd(a, b)}, y = y_0\frac{c}{\gcd(a, b)} - t\frac{a}{\gcd(a, b)}, t \in \mathbb{Z}\)
原方程的最小正整数解为 \(x = (x^{\prime} \bmod \frac{b}{\gcd(a, b)} + \frac{b}{\gcd(a, b)}) \bmod \frac{b}{\gcd(a, b)}\)
\(ax \equiv c(\bmod b)\)
原方程可化为 \(ax + by = c\) 的形式,其中 \(y \in \mathbb{Z}\)
用上面的方法求解即可
注意到有很多解在模 \(b\) 意义下相同
此时有结论:共有 \(\gcd(a, b)\) 个模 \(b\) 意义下不同的解
当通解中的 \(t\) 满足 \(t \in [0, \gcd(a, b) - 1]\) 时取到所有解
模板
ll exgcd(ll a, ll b, ll &x, ll &y)
{
ll d = a;
if (b == 0)
x = 1, y = 0;
else
{
d = exgcd(b, a % b, y, x);
y -= (a / b * x);
}
return d;
}