扩展欧几里得算法 - Exgcd
前置 - 欧几里得算法
- 欧几里得算法是一种求 \(\gcd(a,b)\) 的算法,又名辗转相除法,即为:
\( \gcd(a,b) = \gcd(b,a\bmod b) \)
证明:
令 \(d = \gcd(a,b)\), \(c = a \bmod b = a - k \times b\)($k = \left \lfloor \frac{a}{b} \right \rfloor $)。
\(\therefore 若 \gcd(a,b) = \gcd(b,a \bmod b),则\frac{c}{d}=\frac{a}{d}-\frac{b}{d}k。\)
\(\because \frac{a}{d}-\frac{b}{d}k 为整数\)
\(\therefore \frac{c}{d} 为整数 \therefore d \mid c\)
所以 \(d\) 为 \(b,c\) 的公因数。
接着:
设 \(d \mid b,~d\mid (a \bmod b)\),我们还是可以像之前一样得到以下式子
\(\large\frac{a\bmod b}{d}=\frac{a}{d}-\frac{b}{d}k,~\frac{a\bmod b}{d}+\frac{b}{d}k=\frac{a}{d}\)。
\(\because\) 左边式子显然为整数
\(\therefore \frac{a}{d}\) 也为整数,即 \(d \mid a\),所以 \(b,a\bmod b\) 的公约数也是 \(a,b\) 的公约数。
既然两式公约数都是相同的,那么最大公约数也会相同。
所以得证。
时间复杂度:
若 \(a > 2b\),那么 \(a \bmod b < b\),
若 \(a < 2b\),那么 \(a \bmod b < b\)(因为最多减 1 个 \(b\))
所以,每次 \(a\) 至少缩小 \(\frac{1}{2}\),知道 \(a = 0\) 结束,所以时间复杂度为 \(\text{O}(\log_2 n)\)。
扩展欧几里得 - Exented gcd
主要用来求解线性同余方程和不定方程(这两个是等价的)
0. 特殊的不定方程
该算法用于求解形如:\(ax + by = \gcd(a, b)\) 的不定方程的解。
证明: \(ax + by = \gcd(a, b)\) 一定有解
由于 \(\gcd(a, b) = \gcd(b, a \bmod b)\) (辗转相除)
所以有方程 \(bx_0 + (a \bmod b)y_0 = \gcd(a, b)\)
所以:\(ax + by = bx_0 + (a \bmod b)y_0\)
所以 \(x = y_0, y = x0 - \left \lfloor \frac{a}{b} \right \rfloor y_0\)
依此类推,当 \(a = gcd(a, b), b = 0\) 时,一定有 \(x = 1\),而 \(y\) 有无数种解。
所以,\(ax + by = \gcd(a, b)\) 一定有解。
由上过程,可写出求解一组 \(x, y\) 的代码:
void exgcd(int a, int b, int& x, int& y) {
if (b == 0) {
x = 1, y = 0;
return;
}
exgcd(b, a % b, y, x);
y -= a / b * x;
}
1.求通常不定方程
设一个不定方程为:
\(ax + by = c\)
该方程有解的充要条件 \(c\) 是 \(\gcd(a, b)\) 的倍数。
证明:
设方程 \(ax + by = \gcd(a, b)\)。
两边同时乘以 \(\frac{c}{\gcd(a, b)}\),那么方程就变为:
\(a\frac{c}{\gcd(a, b)}x + b\frac{c}{\gcd(a, b)}y = c\)
由于 \(a, b\) 定义为整数,所以 \(\frac{c}{\gcd(a, b)}\) 为整数,所以 \(c\) 一定整除 \(\gcd(a, b)\)。
于是乎,设 \(ax + by = c\) 的一组解为 \(x, y\),该方程的一组解即为 \(x_0 = x \times c / \gcd(a, b), y_0 = y \times c / \gcd(a, b)\)
2. 通解
对于不定方程 \(ax + by = c\),其所有整数解均满足:
\(x = x_0 + kb / \gcd(a, b)\)
\(y = y_0 - ka / \ gcd(a, b)\)
\(x_0\), \(y_0\) 是 \(ax + by = c\) 的一组解,可以用 Exgcd 求出。
证明:
代回原式:
\(a ( x_0 + kb / \gcd(a, b)) + b(y_0 - ka / \ gcd(a, b)) = c\)
展开:
\( ax_0 + akb / \gcd(a, b)) + by_0 - bka / \ gcd(a, b) = c \)
\( ax_0 + by_0 = c \)
所以成立,得证。