扩展欧几里得

前言

gm今天开了一个数学链接,看了一下发现自己连 Exgcd 都忘了/lh

看来还是有必要写芝士总结了。

扩展欧几里得

就是对辗转相除法求 $\gcd$ 的扩展,主要是用来求解 $a \times x + b \times y = \gcd(a, b)$ 这个二元一次不定方程的。

但是经常地,$a \times x \equiv b \pmod{n}$ 可以转化为 $a \times x + k \times n = b$ 来用 Exgcd 来求解。

回顾辗转相除法的过程,我们是这样求的:

$$ \gcd(a, b) = \gcd(b, a \bmod b) $$

所以满足 $a \times x + b \times y = \gcd(a, b)$ 的 $x$ 和 $y$ 一定满足 $b \times x + (a \bmod b) \times y = \gcd(b, a \bmod b)$。

那么假设有:

$$ \begin{cases} a \times x_{1} + b \times y_{1} = \gcd(a, b)\\ b \times x_{2} + (a \bmod b) \times y_{2} = \gcd(b, a \bmod b) \end{cases} $$

那么可以得到

$$ \begin{aligned} a \times x_{1} + b \times y_{1} &= b \times x_{2} + (a \bmod b) \times y_{2}\\ a \times x_{1} + b \times y_{1} &= b \times x_{2} + (a - \left\lfloor \dfrac{a}{b} \right\rfloor \times b) \times y_{2}\\ a \times x_{1} + b \times y_{1} &= b \times x_{2} + a \times y_{2} - \left\lfloor \dfrac{a}{b} \right\rfloor \times b \times y_{2}\\ a \times x_{1} + b \times y_{1} &= a \times y_{2} - b \times (\left\lfloor \dfrac{a}{b} \right\rfloor \times y_{2} + x_{2})\\ \end{aligned} $$

因为 $a = a, b = b$,所以有:

$$ \begin{cases} a \times x_{1} = a \times y_{2}\\ b \times y_{1} = b \times (\left\lfloor \dfrac{a}{b} \right\rfloor \times y_{2} + x_{2}) \end{cases} \Rightarrow \begin{cases} x_{1} = y_{2}\\ y_{1} = \left\lfloor \dfrac{a}{b} \right\rfloor \times y_{2} + x_{2} \end{cases} $$

所以我们在辗转相除求 $\gcd$ 的时候把 $x$ 和 $y$ 反复带入求值就好了。

在辗转相除最后一步的时候有

$$ a \times x + 0 \times y = a $$

此时 $x = 1, y = 0$ 就好了。

Code:

void Exgcd(ll a, ll b, ll& x, ll& y) {
    if(!b) x = 1, y = 0, g = a;
    else {
        Exgcd(b, a % b, y, x);
        y -= a / b * x;
    }
}
posted @ 2023-10-08 15:17  A_box_of_yogurt  阅读(2)  评论(0编辑  收藏  举报  来源
Document