欧几里德算法:
用途: 得到两个数的最大公约数
公式:
gcd(a,b)=gcd(b,a%b)
证明:
gcd(a,b)=gcd(b,a%b)
- 证明
a,b的公约数一定是
b,a%b的公约数:
因为
a%b=a−⌊ba⌋×b,这里设
c=⌊ba⌋
对于
a,b的任意公约数
d,有
d∣a,d∣b,必然有
d∣(ax+by)
所以
d∣b,d∣(a−c×b)必然成立,即
a,b的公约数一定是
b,a%b的公约数
- 证明
b,a%b的约数数一定是
a,b的公约数:
因为
a%b=a−⌊ba⌋×b,这里设
c=⌊ba⌋
对于
b,a−c×b的任意公约数
d,有
d∣b,d∣(a−c×b),
所以必然有
d∣(a−c×b+c×b)=d∣a,d∣b,即
b,a%b的公约数一定是
a,b的公约数
所以
a,b的公约数集合与
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和
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=x0,y=y0
通解:
x=x0+k×gcd(a,b)b,y=y0−k×gcd(a,b)a
通解证明:
设
d=gcd(a,b)
ax0+by0=d
ax+by=a(x0+k×db)+b(y0−k×da)=ax0+by0+dkab−dkab
=ax0+by0=d
证明代码中的部分:
y=y−a/b×x
证明:
由
exgcd(b,a%b,y,x)得到:
by+(a%b)x=d
即
by+(a−⌊ba⌋×b)x=d
即
ax+b(y−⌊ba⌋x)=d
那么得到的就是
x不变,
y=y−a/b×x