exgcd(扩展欧几里得)学习笔记

exgcd(扩展欧几里得)学习笔记

前置芝士

  • 基础的模、整数运算;
  • $\gcd$ 的求法,即 $\gcd(a, b) = \gcd(b,a \bmod b)$;
  • 裴蜀定理,二元一次方程方程 $ax+by=c$ 有解的充要条件是 $\gcd(a, b) \mid c$;

正文部分

$\tt{exgcd}​$ 用于求出二元一次方程 $ax+by=c​$ 的一组特解。

首先根据裴蜀定理,可以先判掉无解的情况。这样我们可以先计算 $ax+by=\gcd(a,b)$ 这个方程的解,再乘上 $\dfrac{c}{\gcd(a,b)}$。

既然是 $\tt{exgcd}$,那我们考虑 $\gcd$ 是怎么做的,即缩小问题规模,把 $\gcd(a,b)$ 转化为 $\gcd(b, a \bmod b)$ 递归求解。

同样的思路,我们把方程转化为 $bx+(a\bmod b)y=\gcd(b,a \bmod b)$ 递归求解。所以现在的问题是,我们知道一个方程:

的一组解 ${ x_2, y_2}$,求

的一组解 ${ x_1, y_1}$。因为

,所以

然后用拆开取模的小技巧可以得到:

继续化简:

最后得到:

考虑边界,当 $b = 0$ 时,$x = 1$,$y = 0$,时间复杂度与 $\gcd$ 相同, $\Theta(\log \ n)​$。

CODE

1
2
3
4
5
void exgcd(int a, int b, int &x, int &y) {
if (b == 0) {x = 1, y = 0; return;};
exgcd(b, a % b, x, y);
int t = y; y = x - (a / b) * y, x = t;
}

参考OI Wiki