ZT Blog
algorithm

bdfz 2025 winter day1

bdfz 2025 winter day1

GCD

GCD CRT 逆元

扩展欧几里得算法(Exgcd)用于求解方程 ax+by=gcd⁡(a,b)ax + by = \gcd(a, b) 的整数解 xx 和 yy,同时返回 aa 和 bb 的最大公约数。以下是代码的逐层解释:

递归终止条件

当 b=0b = 0 时,方程为 a⋅1+0⋅0=aa \cdot 1 + 0 \cdot 0 = a,此时:

  • x=1x = 1, y=0y = 0

  • 直接返回 aa(最大公约数)

递归过程

  1. 递归调用:计算 gcd⁡(b,a%b)\gcd(b, a \% b),得到解 x′x' 和 y′y',满足:
b⋅x′+(a%b)⋅y′=gcd⁡(b,a%b)b \cdot x' + (a \% b) \cdot y' = \gcd(b, a \% b)

根据欧几里得算法,gcd⁡(a,b)=gcd⁡(b,a%b)\gcd(a, b) = \gcd(b, a \% b)。

  1. 转换解:将递归结果的解 x′x' 和 y′y' 转换为当前层的解 xx 和 yy。利用 a%b=a−⌊a/b⌋⋅ba \% b = a - \lfloor a/b \rfloor \cdot b,原方程可重写为:
a⋅y′+b⋅(x′−⌊a/b⌋⋅y′)=gcd⁡(a,b)a \cdot y' + b \cdot (x' - \lfloor a/b \rfloor \cdot y') = \gcd(a, b)

因此:

  • x=y′x = y'

  • y=x′−⌊a/b⌋⋅y′y = x' - \lfloor a/b \rfloor \cdot y'

代码步骤

  • 保存递归前的 xx:int t = x(此时 x=x′x = x')。

  • 更新 xx:x = y(将 xx 设为 y′y')。

  • 更新 yy:y = t - (a / b) * y(计算 y=x′−⌊a/b⌋⋅y′y = x' - \lfloor a/b \rfloor \cdot y')。

示例分析

以 a=30a = 30, b=12b = 12 为例:

  1. 递归至 gcd⁡(6,0)\gcd(6, 0),返回 x=1x = 1, y=0y = 0, gcd⁡=6\gcd = 6。

  2. 回溯到 gcd⁡(12,6)\gcd(12, 6),计算 x=0x = 0, y=1y = 1,满足 12⋅0+6⋅1=612 \cdot 0 + 6 \cdot 1 = 6。

  3. 回溯到 gcd⁡(30,12)\gcd(30, 12),计算 x=1x = 1, y=−2y = -2,满足 30⋅1+12⋅(−2)=630 \cdot 1 + 12 \cdot (-2) = 6。

总结

代码通过递归分解问题,逐步缩小规模。每次递归后,利用子问题的解 x′x' 和 y′y' 推导当前层的解 xx 和 yy,最终得到满足 ax+by=gcd⁡(a,b)ax + by = \gcd(a, b) 的整数解。

CRT