欧几里德算法
证明
证明欧几里德算法的关键是要证明gcd(a,b)==gcd(b mod a,a)
b mod a 等价于 b - ⌊b/a⌋ *a
b - ⌊b/a⌋ *a 能被 gcd( a , b )整除
又因为 a 和 b 都能被 gcd( a , b )整除
所以 b mod a 和 a 也能被 gcd( a , b )整除
code
int gcd(int a,int b){
return b==0?a:gcd(b,a%b);
}
扩展欧几里德算法
如果a和b都是整数,则有整数x和y 使得 ax+by=GCD(a,b)
推论 若a,b互素,则存在x和y使得ax+by=1
证明
设c是a和b的线性组合中最小整数
ax+by=c (x,y 为整数)
令 a=cq+r (0<=r<c)
可得 r=a-cq=a(1-qx)-bqy
所以 r 是 a 和 b 的线性组合
又因为 c是a和b的线性组合中最小整数
所以 r == 0
所以 c 是 a 的约数
同理 c 是 b 的约数
所以 c 是 a 和 b 的公约数
对于 a 和 b 的所有约数 d
因为 ax + by = c
所以 d 是 c 的约数 c>=d;
所以 c 是 最大公约数 GCD (a , b)
应用
因为 a x1+b y1=GCD(a,b) , a x2+GCD(b,a%b) y2=GCD(b,a%b)=GCD(a,b)
所以 a x1+b y1=b x2+(a - ⌊a/b⌋ *b) y2=a y2 + b(x2-⌊a/b⌋ * y2)
所以 x1=y2, y1=x2-⌊a/b⌋ * y2
重复这一过程 直到 b==0 此时 x=1,y=0。
结论
x1=y2
y1=x2 - ⌊a/b⌋ * y2
code
int exgcd(int a,int b,int &x, int &y){
if(b==0){ x=1,y=0;return a;}
int t=exgcd(b,a%b,x,y);
int x0=x,y0=y;
x=y0,y=x0-(a/b)*y0;
return t;
}
&是引用的符号,一变全变