欧几里德算法+扩展欧几里德算法

欧几里德算法

在这里插入图片描述

证明

证明欧几里德算法的关键是要证明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;
}

&是引用的符号,一变全变

猜你喜欢

转载自blog.csdn.net/weixin_44410512/article/details/89787981