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

欧几里得算法:

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

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

  1. 证明:

令 d=gcd(a,b)⇒a=m⋅d,b=n⋅dd = gcd(a, b) \Rightarrow a = m \cdot d, b = n \cdot d

则 m⋅d=t⋅n⋅d+a%b⇒a%b=d⋅(m−t⋅n)m \cdot d = t \cdot n \cdot d + a \% b \Rightarrow a \% b = d \cdot (m - t \cdot n)

gcd(b,a%b)=gcd(n⋅d,(m−t⋅n)⋅d)gcd(b, a \% b) = gcd(n \cdot d, (m - t \cdot n) \cdot d)

令 gcd(n,m−t⋅n)=e⇒n=x⋅e,m−t⋅n=y⋅egcd(n, m - t \cdot n) = e \Rightarrow n = x \cdot e, m - t \cdot n = y \cdot e

则 m−x⋅e⋅n=y⋅e⇒m=e⋅(x⋅n+y)m - x \cdot e \cdot n = y \cdot e \Rightarrow m = e \cdot (x \cdot n + y)

由 gcd(n,m)=1gcd(n, m) = 1 知 gcd(e⋅(x⋅n+y),e⋅x)=1gcd(e \cdot (x \cdot n + y), e \cdot x) = 1

故 e=1e = 1

故 gcd(n⋅d,(m−t⋅n)⋅d)=dgcd(n \cdot d, (m - t \cdot n) \cdot d) = d 即 gcd(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 ,这里的 aa 和 bb 是上一层的,满足 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. 丢番图方程:

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

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

  1. 裴蜀定理:

对于正整数 aa 和 bb ,令 gcd(a,b)=dgcd(a, b) = d ,则对于任意整数 xx 和 yy ,都有 d∣(a⋅x+b⋅y)d|(a \cdot x + b \cdot y)

证明:

令 a=n⋅d,b=m⋅da = n \cdot d, b = m \cdot d,则 a⋅x+b⋅y=d⋅n⋅x+d⋅m⋅ya \cdot x + b \cdot y = d \cdot n \cdot x + d \cdot m \cdot y

显然 d∣(d⋅n⋅x+d⋅m⋅y)d|(d \cdot n \cdot x + d \cdot m \cdot y)

  1. 引理:

丢番图方程 a⋅x+b⋅y=ca \cdot x + b \cdot y = c 有解当且仅当 d∣cd|c

对于任意整数 xx 和 yy ,a⋅x+b⋅ya \cdot x + b \cdot y 的最小正值为 gcd(a,b)gcd(a, b)

证明:

①必要性:

由裴蜀定理,不存在整数 xx 和 yy ,使得 dd 不整除 (a⋅x+b⋅y)(a \cdot x + b \cdot y)

②充分性:

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

令对于 ∀x,y∈Z\forall x, y \in Z ,a⋅x+b⋅ya \cdot x + b \cdot y 能得到的最小正值为 ss

由裴蜀定理,d∣sd|s ,则 d≤sd \leq s

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

则 p=a−q⋅(a⋅x+b⋅y)=a⋅(1−q⋅x)−q⋅b⋅y=a⋅(1−q⋅x)+b⋅(−q⋅y)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 \% s 知 0≤p<s0 \leq p < s

又 ss 为 a⋅x+b⋅ya \cdot x + b \cdot y 能得到的最小正值

故 p=0p = 0 ,即 s∣as|a

同理,s∣bs|b ,即 s∣ds|d ,故 s≤ds \leq d

综上,s=ds = d

即对于 ∀x,y∈Z\forall x, y \in Z ,a⋅x+b⋅ya \cdot x + b \cdot y 能得到的最小正值为 dd

故 ∃x,y∈Z\exists x, y \in Z ,使 a⋅x+b⋅y=da \cdot x + b \cdot y = d

即 ∃x,y∈Z\exists x, y \in Z ,使 a⋅x+b⋅y=ca \cdot x + b \cdot y = c

  1. 扩展欧几里得算法:

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

令
a⋅x1+b⋅y1=gcd(a,b)a \cdot x_1 + b \cdot y_1 = gcd(a, b)

b⋅x2+(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) 知

a⋅x1+b⋅y1=b⋅x2+(a%b)⋅y2a \cdot x_1 + b \cdot y_1 = b \cdot x_2 + (a \% b) \cdot y_2

=b⋅x2+(a−b⋅⌊ab⌋)⋅y2=a⋅y2+b⋅(x2−⌊ab⌋⋅y2)= 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=(x2−⌊ab⌋⋅y2)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 )

a⋅x+b⋅y=a⋅x=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 = 1 ,yy 可以为任何值,通常设为 00 ,减少溢出的风险

yy 的多值对应方程的多解

  1. 通解:

对于对于第一个解 x0x_0 和 y0y_0 ,其他解可以表示为 x0+bd⋅kx_0 + \frac{b}{d} \cdot k 和 y0−ad⋅ky_0 - \frac{a}{d} \cdot k

推导:

令 a⋅(x+m)+b⋅(x−n)=da \cdot (x + m) + b \cdot (x - n) = d

⇒a⋅m=b⋅n⇒mn=ba\Rightarrow a \cdot m = b \cdot n \Rightarrow \frac{m}{n} = \frac{b}{a}

因 gcd(a,b)=dgcd(a, b) = d ,mm 和 nn 均为整数

故 mm 和 nn 的最小值分别为 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 同余方程