GCD(欧几里德算法)和EXGCD(扩展欧几里德算法)

欧几里得算法:

  1. 定义:gcd 的意思是最大公约数,通常用扩展欧几里得算法求

原理:gcd(a,b)=gcd(b,a%b)gcd(a, b) = gcd(b, a \% b)

  1. 证明:

d=gcd(a,b)a=md,b=ndd = gcd(a, b) \Rightarrow a = m \cdot d, b = n \cdot d

md=tnd+a%ba%b=d(mtn)m \cdot d = t \cdot n \cdot d + a \% b \Rightarrow a \% b = d \cdot (m - t \cdot n)

gcd(b,a%b)=gcd(nd,(mtn)d)gcd(b, a \% b) = gcd(n \cdot d, (m - t \cdot n) \cdot d)

gcd(n,mtn)=en=xe,mtn=yegcd(n, m - t \cdot n) = e \Rightarrow n = x \cdot e, m - t \cdot n = y \cdot e

mxen=yem=e(xn+y)m - x \cdot e \cdot n = y \cdot e \Rightarrow m = e \cdot (x \cdot n + y)

gcd(n,m)=1gcd(n, m) = 1gcd(e(xn+y),ex)=1gcd(e \cdot (x \cdot n + y), e \cdot x) = 1

e=1e = 1

gcd(nd,(mtn)d)=dgcd(n \cdot d, (m - t \cdot n) \cdot d) = dgcd(b,a%b)=gcd(a,b)gcd(b, a \% b) = gcd(a, b)

  1. 边界:

当 b = 0 时 return a

可以视为 gcd(a,0)=agcd(a, 0) = a ,任何数都能整除 00

也可以视为 gcd(a,b)=bgcd(a, b) = b ,这里的 aabb 是上一层的,满足 a%b=0a \% b = 0

  1. 特殊情况:
    当 a < b 时,a%b = a,所以在下一层 gcd(b, a%b) 中相当于把 a 与 b 交换

  2. 代码:

1
int gcd(int a,int b){  return b ? gcd(b,a%b) : a;}

扩展欧几里得算法:

  1. 丢番图方程:

有一个或者几个变量的整系数方程,它们的求解仅仅在整数范围内进行。

扩展欧几里得算法研究的是形如 ax+by=ca \cdot x + b \cdot y = c 的丢番图方程的解

  1. 裴蜀定理:

对于正整数 aabb ,令 gcd(a,b)=dgcd(a, b) = d ,则对于任意整数 xxyy ,都有 d(ax+by)d|(a \cdot x + b \cdot y)

证明:

a=nd,b=mda = n \cdot d, b = m \cdot d,则 ax+by=dnx+dmya \cdot x + b \cdot y = d \cdot n \cdot x + d \cdot m \cdot y

显然 d(dnx+dmy)d|(d \cdot n \cdot x + d \cdot m \cdot y)

  1. 引理:

丢番图方程 ax+by=ca \cdot x + b \cdot y = c 有解当且仅当 dcd|c

对于任意整数 xxyyax+bya \cdot x + b \cdot y 的最小正值为 gcd(a,b)gcd(a, b)

证明:

①必要性:

由裴蜀定理,不存在整数 xxyy ,使得 dd 不整除 (ax+by)(a \cdot x + b \cdot y)

②充分性:

要证 ax+by=ca \cdot x + b \cdot y = c 有解,只需 ax+by=da \cdot x + b \cdot y = d 有解

令对于 x,yZ\forall x, y \in Zax+bya \cdot x + b \cdot y 能得到的最小正值为 ss

由裴蜀定理,dsd|s ,则 dsd \leq s

q=as,p=a%sq = \lfloor \frac{a}{s} \rfloor, p = a \% s

p=aq(ax+by)=a(1qx)qby=a(1qx)+b(qy)p = a - q \cdot (a \cdot x + b \cdot y) = a \cdot (1 - q \cdot x) - q \cdot b \cdot y = a \cdot (1 - q \cdot x) + b \cdot (-q \cdot y)

p=a%sp = a \% s0p<s0 \leq p < s

ssax+bya \cdot x + b \cdot y 能得到的最小正值

p=0p = 0 ,即 sas|a

同理,sbs|b ,即 sds|d ,故 sds \leq d

综上,s=ds = d

即对于 x,yZ\forall x, y \in Zax+bya \cdot x + b \cdot y 能得到的最小正值为 dd

x,yZ\exists x, y \in Z ,使 ax+by=da \cdot x + b \cdot y = d

x,yZ\exists x, y \in Z ,使 ax+by=ca \cdot x + b \cdot y = c

  1. 扩展欧几里得算法:

通常将求解 ax+by=ca \cdot x + b \cdot y = c 转化为求解 ax+by=gcd(a,b)a \cdot x + b \cdot y = gcd(a, b) ,得解后乘上 cgcd(a,b)\frac{c}{gcd(a, b)} 即可


ax1+by1=gcd(a,b)a \cdot x_1 + b \cdot y_1 = gcd(a, b)

bx2+(a%b)y2=gcd(b,a%b)b \cdot x_2 + (a \% b) \cdot y_2 = gcd(b, a \% b)

gcd(a,b)=gcd(b,a%b)gcd(a, b) = gcd(b, a \% b)

ax1+by1=bx2+(a%b)y2a \cdot x_1 + b \cdot y_1 = b \cdot x_2 + (a \% b) \cdot y_2

=bx2+(abab)y2=ay2+b(x2aby2)= b \cdot x_2 + (a - b \cdot \lfloor \frac{a}{b} \rfloor) \cdot y_2 = a \cdot y_2 + b \cdot (x_2 - \lfloor \frac{a}{b} \rfloor \cdot y_2)

x1=y2,y1=(x2aby2)x_1 = y_2, y_1 = (x_2 - \lfloor \frac{a}{b} \rfloor \cdot y_2)

如此递归直至边界情况

  1. 边界:

b=0b = 0 时,gcd(a,b)=agcd(a, b) = a(任何数都能整除 00

ax+by=ax=gcd(a,b)xa \cdot x + b \cdot y = a \cdot x = gcd(a, b) \cdot x

若使 a\*x + b\*y = gcd(a, b) ,只需 x=1x = 1yy 可以为任何值,通常设为 00 ,减少溢出的风险

yy 的多值对应方程的多解

  1. 通解:

对于对于第一个解 x0x_0y0y_0 ,其他解可以表示为 x0+bdkx_0 + \frac{b}{d} \cdot ky0adky_0 - \frac{a}{d} \cdot k

推导:

a(x+m)+b(xn)=da \cdot (x + m) + b \cdot (x - n) = d

am=bnmn=ba\Rightarrow a \cdot m = b \cdot n \Rightarrow \frac{m}{n} = \frac{b}{a}

gcd(a,b)=dgcd(a, b) = dmmnn 均为整数

mmnn 的最小值分别为 bd\frac{b}{d}ad\frac{a}{d}

若要求其中一个解为正整数,可在得到负解后用通解转化为正数

  1. 代码:
1
2
3
4
5
6
7
8
9
void exgcd(int a,int b,int &x,int &y){
if(!b){
x=1,y=0;
return ;
}
exgcd(b,a%b,x,y);
int z=x;
x=y,y=(z-a/b*y);
}
  1. 易错点:

算法中存在乘法,有溢出的风险,应见机开 long long

例题:

洛谷4549 裴蜀定理

洛谷1516 青蛙的约会

洛谷3951 小凯的疑惑

洛谷1082 同余方程