欧几里德算法:
用途: 得到两个数的最大公约数
公式: g c d ( a , b ) = g c d ( b , a % b ) gcd(a,b)=gcd(b,a\%b) gcd(a,b)=gcd(b,a%b)
证明: g c d ( a , b ) = g c d ( b , a % b ) gcd(a,b)=gcd(b,a\%b) gcd(a,b)=gcd(b,a%b)
所以 a , b a,b a,b的公约数集合与 b , a % b b,a\%b b,a%b的公约数集合一致,所以 g c d ( a , b ) = g c d ( b , a % b ) gcd(a,b)=gcd(b,a\%b) gcd(a,b)=gcd(b,a%b)
代码:
int gcd(int a, int b) {
return b == 0 ? a : gcd(b, a % b);
}
扩展欧几里德算法:
定义: 对于 a a a和 b b b,一定存在 a x + b y = g c d ( a , b ) ax+by=gcd(a,b) ax+by=gcd(a,b)
代码:
void exgcd(int a, int b, int &x, int &y) {
if(!b) {
x = 1;
y = 0;
return ;
}
exgcd(b, a % b, y, x);
y -= a / b * x;
}
得到的 x = x 0 , y = y 0 x=x_0,y=y_0 x=x0,y=y0
通解: x = x 0 + k × b g c d ( a , b ) , y = y 0 − k × a g c d ( a , b ) x=x_0+k\times \frac{b}{gcd(a,b)},y=y_0-k\times \frac{a}{gcd(a,b)} x=x0+k×gcd(a,b)b,y=y0−k×gcd(a,b)a
通解证明:
设 d = g c d ( a , b ) d = gcd(a,b) d=gcd(a,b)
a x 0 + b y 0 = d ax_0+by_0=d ax0+by0=d
a x + b y = a ( x 0 + k × b d ) + b ( y 0 − k × a d ) = a x 0 + b y 0 + k a b d − k a b d ax+by=a(x_0+k\times \frac{b}{d})+b(y_0-k\times \frac{a}{d})=ax_0+by_0+\frac{kab}{d}-\frac{kab}{d} ax+by=a(x0+k×db)+b(y0−k×da)=ax0+by0+dkab−dkab
= a x 0 + b y 0 = d =ax_0+by_0=d =ax0+by0=d
证明代码中的部分: y = y − a / b × x y = y - a / b \times x y=y−a/b×x
证明:
由 e x g c d ( b , a % b , y , x ) exgcd(b,a\%b,y,x) exgcd(b,a%b,y,x)得到:
b y + ( a % b ) x = d by+(a\%b)x=d by+(a%b)x=d
即 b y + ( a − ⌊ a b ⌋ × b ) x = d by+(a-\lfloor \frac{a}{b} \rfloor \times b)x=d by+(a−⌊ba⌋×b)x=d
即 a x + b ( y − ⌊ a b ⌋ x ) = d ax+b(y-\lfloor \frac{a}{b} \rfloor x)=d ax+b(y−⌊ba⌋x)=d
那么得到的就是 x x x不变, y = y − a / b × x y=y-a/b\times x y=y−a/b×x