欧几里得算法
辗转相除法,设 a≥b 原理是:
gcd(a,b)=gcd(b,a−b)
这个原因是 gcd(a,b)∣a,gcd(a,b)∣b,所以相减同样满足 gcd(a,b)∣(a−b)。
我们知道取模实际上是减法,所以同理可得:
gcd(a,b)=gcd(b,amodb)
实现起来就是:
1 2 3 4
| int gcd(int a, int b) { if (!b) return a; return gcd(b, a % b); }
|
拓展欧几里得算法
裴蜀定理:对于任意正整数 a,b 一定存在非零整数 x,y 使 ax+by=gcd(a,b)
如果已知:
by+(amodb)x=d
则能递推出:
by+(a−⌊ba⌋b)xax+b(y−⌊ba⌋x)=d=d
然后就写出 exgcd
算法求一组解了。
1 2 3 4 5 6
| int exgcd(int a, int b, int& x, int& y) { if (b == 0) return x = 1, y = 0, a; int d = exgcd(b, a%b, y, x); y -= a/b * x; return d; }
|
由于 ax0+by0=d,那么满足条件的所有 x,y 一定也满足:
a(x+db)+b(y−da)=d
也就有通解如下:
⎩⎨⎧xyk=x0+kdb=y0−kda∈Z
除以 d 后这个数仍为整数。