欧几里得算法
首先感谢 C20210413 大佬, C20211711LJS 社花大佬,14大佬对于正确使用 \(markdown\) 语法给予的帮助
人物介绍
欧几里得:(英文:\(Euclid\);希腊文:Ευκλειδης ,约公元前330年—公元前275年),古希腊人,数学家,被称为“几何之父”。他最著名的著作《几何原本》是欧洲数学的基础,提出五大公设,欧几里得几何,被广泛的认为是历史上最成功的教科书。欧几里得也写了一些关于透视、圆锥曲线、球面几何学及数论的作品。
算法本身
欧几里得算法,即辗转相除法,用于求 \(a, b\) 两数的最大公约数数------ \(\gcd(a, b)\)
结论:\(\gcd(a, b) = \gcd(b, a \bmod b)\)
证明:我们设 \(r = a \bmod b\),显然 \(r\) 也可以表示为 \(r = a - k \times b\),其中 \(k = a / b\)。
假设 \(d\) 是 \(a, b\) 的一个公约数,则有:\(a \bmod d = 0\),\(b \bmod d = 0\)。
设 \(a = x \times d, b = y \times d\),且 \(x, y\) 为整数。而 \(r = a - k \times b\)。
所以 \(r = x \times d - y \times d \times k = (x - k \times y) \times d\),显然,\(x - k \times y\) 为整数。
所以 \(r\) 是 \(d\) 的倍数。所以 \(r \bmod d = 0\),又因为 \(b \bmod d = 0\),且 \(r = a \bmod b\)。
所以有:\(d = \gcd(b, a \bmod b)\)
根据以上原理,经过一步代换后,一定会出现 \(a > b\)。以后的每次代换一定会将 \(a, b\) 不断的缩小,而当 \(b = 0\) 时,它们的最大公约数为 \(a\)。
代码实现
int gcd(int a, int b) {
if(b == 0) return a;
return gcd(b, a % b);
}
已被严格证明时间复杂度为:\(O(\log\ max(a, b))\)
扩展欧几里得算法
简称扩欧。
可以在已知整数 \(a, b\) 的情况下求不定方程 \(a \times x + b \times y = \gcd(a, b)\) 的一组整数解。
首先,我们来证明一个结论:对于整数 \(a, b\),必定存在整数 \(x, y\) 满足 \(a \times x + b \times y = \gcd(a, b)\)。
证明:设 \(a \times x1 + b \times y1 = \gcd(a, b)\),且 \(b \times x2 + (a \bmod b) \times y2 = \gcd(b, a \bmod b)\)。
由欧几里得算法知:\(\gcd(a, b) = \gcd(b, a \bmod b)\)。
所以 \(a \times x1 + b \times y1 = b \times x2 + (a \bmod b) \times y2\)。
因为 \(a \bmod b = a - b \times k\),所以 \(a \times x1 + b \times y1 = b \times x2 + (a - b \times k) \times y2\)。
又因为 \(k = a / b\),所以 \(a \times x1 + b \times y1 = b \times x2 + (a - b \times (a / b)) \times y2\)
整理得,\(a \times x1 + b \times y1 = a \times y2 + b \times (x2 - (a / b) \times y2)\)
显然,\(x1 = y2, y1 = (x2 - (a / b) \times y2)\),其中 \(x2, y2\) 是关于 \(\gcd(b, a\bmod b)\) 的不定方程的解。这就和欧几里得算法联系起来了,因为 \(x1, x2\) 是由 \(x2, y2\) 得来的,且 \(x2, y2\) 关于 \(\gcd(b, a \bmod b)\) 不断变小。
最后,当 \(x, y\) 是关于 \(\gcd(a, 0)\) 的不定方程的解时,不难发现 \(a \times x + b \times y = a\), 所以此时 \(x = 1, y = 0\)。这就是递归求解的边界。故因为边界确定,所以对于整数 \(a, b\),必定存在整数 \(x, y\) 满足 \(a \times x + b \times y = \gcd(a, b)\)。
不难通过刚刚的证明过程,写出代码:
long long x, y;
void Ex_Gcd(long long a, long long b) {
if(b == 0) {
x = 1;
y = 0;
return ;
}
Ex_Gcd(b, a % b);
long long t = x;
x = y;
y = t - a / b * y;
}
应用
Part 1 判断不定方程 \(a \times x + b \times y = c\) 是否有解
根据扩欧:假设 \(d = \gcd(a, b)\) ,则 \(a \times x + b \times y = d\) 一定有解。
所以 \((a \times x + b \times y) \times k = d \times k\) 一定有解 (\(k\) 为整数)。
显然 \(a \times x + b \times y = d \times k\) 一定有解。
所以不定方程 \(a \times x + b \times y = c\) 中当 \(c \bmod \gcd(a, b) = 0\) 时,方程有解。否则无解。
Part 2 不定方程 \(a \times x + b \times y = c\) 的通解
对于不定方程 \(a \times x + b \times y = c\),我们设 \(d = \gcd(a, b)\)。当 \(c \bmod d = 0\) 时有解。
利用扩欧求出 \(a \times x' + b \times y' = \gcd(a, b) = d\) 的一组解 \(x', y'\)。
则 \(a \times x + b \times y = c\) 一定有一组解为 \(x = x' \times c / d, y = y' \times c / d\)。
又因为原方程可化为 \(a \times x + k \times a \times b + b \times y - k \times a \times b = c\)。其中 \(k\) 为整数。
即 \(a \times (x + b \times k) + b \times (y - a \times k) = c\)。
所以 :
\(x = x' \times c / d + b \times k / d\)
\(y = y' \times c / d - a \times k / d\)
Part 3 模线性方程 \(a \times x \equiv b\) \((mod\) \(n)\) 的解
首先,如果 \(a \equiv b\) \((mod\) \(n)\),则 \((a - b) \bmod n = 0\)。
所以,如果 \(a \times x \equiv b\) \((mod\) \(n)\),则 \((a \times x - b) \bmod n = 0\)。
于是,我们设 \(a \times x - b = n \times y\),其中 \(y\) 为整数。
那么模线性方程 \(a \times x \equiv b\) \((mod\) \(n)\)可化为不定方程 \(a \times x - n \times y = b\)。
解法详见 \(Part 2\)。
Part 4 乘法逆元
首先,\(a \times x \equiv1\) \((mod\) \(n)\)的解称为 \(a\) 关于模 \(n\) 的乘法逆元。
什么情况下 \(a\) 的逆元存在?由 \(Part 3\) 可得当 \(ax - ny = 1\) 有解时,存在 \(a\) 的逆元。
所以由 \(Part 1\) 得 \(1\) 是 \(\gcd(a, n)\) 的倍数。所以 \(\gcd(a, n) = 1\),即 \(a\) 和 \(n\) 互质。
故,在 \(\gcd(a, n) = 1\) 的前提下,\(a \times x \equiv1\) \((mod\) \(n)\)的解就是 \(a\) 关于模 \(n\) 的乘法逆元。
(其中, \(x < n\) 或者说 \(x = x \bmod n\))
补充
1.费马小定理
费马: 皮埃尔·德·费马,法国律师和业余数学家。他在数学上的成就不比职业数学家差,他似乎对数论最有兴趣,亦对现代微积分的建立有所贡献。被誉为“业余数学家之王”。
定理本身: 如果 \(p\) 为质数,且 \(a\) 与 \(p\) 互质,即 \(\gcd(a, p) = 1\),那么一定有 \(a^{p - 1} \equiv 1\) \((mod\) \(p)\)
求乘法逆元: 因为 \(a^{p - 1} \equiv 1\) \((mod\) \(p)\),所以 \(a \times a^{p - 2} \equiv 1\) \((mod\) \(p)\)。故 \(a^{p - 2}\) 就是 \(a\) 关于模 \(p\) 的乘法逆元
2.关于同余的一些证明
- 1) 如果 \(a \equiv b\) \((mod\) \(m)\),\(x \equiv y\) \((mod\) \(m)\),则 \(a + x \equiv b + y\) \((mod\) \(m)\)。
证明:首先,我们一定能找到 \(k_a\) 与 \(k_b\) 使得 \(a - k_a \times m = b - k_b \times m\),也存在 \(k_x\) 与 \(k_y\) 使得 \(x - k_x \times m = y - k_y \times m\)。
所以 \(a - k_a \times m + x - k_x \times m = b - k_b \times m + y - k_y \times m\),即 \(a + x - m \times (k_a + k_x) = b + y - m \times (k_b + k_y)\)。
故 \(a + x \equiv b + y\) \((mod\) \(m)\)
- 2) 如果 \(a \equiv b\) \((mod\) \(m)\),\(x \equiv y\) \((mod\) \(m)\),则 \(a \times x \equiv b \times y\) \((mod\) \(m)\)。
证明:首先,我们一定能找到 \(k_a\) 与 \(k_b\) 使得 \(a - k_a \times m = b - k_b \times m\),也存在 \(k_x\) 与 \(k_y\) 使得 \(x - k_x \times m = y - k_y \times m\)(同上)。
所以 \((a - k_a \times m) \times (x - k_x \times m) = (b - k_b \times m) \times (y - k_y \times m)\),展开后必然得到 \(a \times x - m \times (...) = b \times y - m \times (...)\)。
故 \(a \times x \equiv b \times y\) \((mod\) \(m)\)
- 3) 如果 \(a \times c \equiv b \times c\) \((mod\) \(m)\),\(\gcd(c, m) = 1\),则 \(a \equiv b\) \((mod\) \(m)\)。
证明:首先,我们一定能找到 \(k_{ac}\) 与 \(k_{bc}\) 使得 \(a \times c - k_{ac} \times m = b \times c - k_{bc} \times m\)。移项可得 \(a \times c - b \times c = k_{ac} \times m - k_{bc} \times m\),即 \((a - b) \times c = m \times (k_{ac} - k_{bc})\)
又因为 \(\gcd(c, m) = 1\) 所以 \((a - b)\) 一定被 \(m\) 整除。
故 \(a \equiv b\) \((mod\) \(m)\)。
完结撒花~