扩展欧几里得算法 - 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 \)

所以成立,得证。

posted @ 2023-09-06 17:13  固态H2O  阅读(5)  评论(0编辑  收藏  举报  来源