如何优雅流畅且简洁易懂幽默风趣地证明欧几里得算法和裴蜀定理
本文中的方法出自华罗庚的《数论导引》。
关于模的研究
话说这个东西到底叫什么,整数加法群的一个子群吗?
一个模是一个整数的集合,使得对于这个集合内的任意两个数
例如,
然后我们来研究一些模的性质。
(1)如果一个模非空,那么
0 一定在这个模中。
因为模非空,所以至少一个整数
(2)若
a, b 是整数,则\{ax+by\mid x, y\in\mathbb{Z}\} 是一个模。
这是显然的。
(3)对于任意一个模(
\{0\} 还有\varnothing 除外),设a 是模中的最小的正整数,则这个模中所有元素都是a 的整数倍。
假设存在一个
因为
但是,
显然
由此而来的裴蜀定理
考虑
欧几里得算法——最大公因数变成模
观察(3)的证明,我们可以发现,要求
下面设
令
关于它的复杂度
首先,有一个引理,在 CF 题目 中曾经出现,具体证明可以查看该题题解:
当
x\gt y 时,x\operatorname{mod}y\lt\frac{x}{2} 。
所以每次
在剩余的东西中找到扩展欧几里得算法
刚才我们知道了
首先我们已知这几个事实:
-
-
- 我们只要找到
ax+by=\gcd(a, b) 的解即可,因为假设它的一个解是(x_0, y_0) ,那么ax+by=k 有一个解(\frac{k}{\gcd(a, b)}x_0, \frac{k}{\gcd(a, b)}y_0) 。
于是我们就可以在回溯时求出解了。假设已经找到一对
这也可以在递归的过程中实现:
std::tuple<int, int, int> exgcd(int a, int b) {
if(!b) return {a, 1, 0};
int g, x, y;
std::tie(g, x, y)=exgcd(b, a%b);
return {g, y, x-y*(a/b)};
}
希望你能从这篇文章中学到什么,谢谢!