当 b = 0 时,gcd(a, 0) = a,此时解为 x = 1, y = 0。 当 b > 0 时,我们有:
text
gcd(a, b) = gcd(b, a mod b)
假设我们已经求出了下一层的解 (x₁, y₁),使得:
text
b·x₁ + (a mod b)·y₁ = gcd(b, a mod b) = gcd(a, b)
而 a mod b = a - floor(a/b)·b,代入并整理,最终得到:
text
x = y₁y = x₁ - floor(a/b)·y₁
这就是递归回溯时的更新公式。
C++ 实现
cpp
// 返回 gcd(a,b),并将 x, y 设置为满足 ax + by = gcd(a,b) 的一组解intextended_gcd(int a,int b,int&x,int&y){if(b ==0){ x =1; y =0;return a;}int x1, y1;int d =extended_gcd(b, a % b, x1, y1); x = y1; y = x1 -(a / b)* y1;return d;}
测试一下:求 35 和 15 的贝祖等式解。
cpp
int x, y;int g =extended_gcd(35,15, x, y);// g = 5, x = 1, y = -2 → 35*1 + 15*(-2) = 35 - 30 = 5 ✅
应用一:求解线性同余方程
线性同余方程形如:a·x ≡ b (mod m)。它有解当且仅当 gcd(a, m) | b。解可以通过扩展欧几里得求出:
先用扩展欧几里得求 a·x0 + m·y0 = gcd(a, m)。
两边乘以 b / g,得到 a·(x0 * (b/g)) ≡ b (mod m)。
模 m 下的解为 x = (x0 * (b/g) % m + m) % m。
C++ 实现:
cpp
// 求解 a*x ≡ b (mod m),返回最小非负整数解,若无解返回 -1intlinear_congruence(int a,int b,int m){int x, y;int g =extended_gcd(a, m, x, y);if(b % g !=0)return-1;int x0 = x *(b / g)% m;if(x0 <0) x0 += m;return x0;}
三、模逆元:除法在模世界中的化身
在模运算中,我们无法直接做除法,而是乘以“逆元”。如果 a·x ≡ 1 (mod m),则 x 称为 a 在模 m 下的逆元,记作 a⁻¹。
逆元存在的条件
gcd(a, m) = 1,即 a 与 m 互质。
求逆元的方法
方法一:扩展欧几里得(通用)
cpp
intmod_inverse(int a,int m){int x, y;int g =extended_gcd(a, m, x, y);// 要求 a 和 m 互质,否则不存在逆元if(g !=1)return-1;return(x % m + m)% m;// 保证为正}
方法二:费马小定理(m 为素数时)
如果 m 是素数,则 a^(m-2) ≡ a⁻¹ (mod m),可以用快速幂在 O(log m) 时间内求解。
cpp
intmod_pow(int a,int b,int mod){int res =1;while(b){if(b &1) res =1LL* res * a % mod; a =1LL* a * a % mod; b >>=1;}return res;}intmod_inverse_prime(int a,int p){returnmod_pow(a, p-2, p);}
// 要求 mod[] 中元素两两互质,rem[] 是对应的余数,k 是方程个数intcrt(int rem[],int mod[],int k){int M =1;for(int i =0; i < k;++i) M *= mod[i];int result =0;for(int i =0; i < k;++i){int Mi = M / mod[i];int inv =mod_inverse(Mi, mod[i]);// 扩展欧几里得求逆元 result =(result +1LL* rem[i]* Mi % M * inv)% M;}return result;}
例子
解方程组:
text
x ≡ 2 (mod 3)x ≡ 3 (mod 5)x ≡ 2 (mod 7)
M = 3×5×7 = 105 i=0: M₁=35, inv₁=2 (因为 35 mod 3 = 2, 2×2=4≡1 mod3) → 贡献 2×35×2=140 i=1: M₂=21, inv₂=1 (21 mod5=1) → 贡献 3×21×1=63 i=2: M₃=15, inv₃=1 (15 mod7=1) → 贡献 2×15×1=30 总和 = 140+63+30=233,233 mod 105 = 23。验证:23 mod 3 = 2, mod 5 = 3, mod 7 = 2 ✅
五、扩展到非互质模数的中国剩余定理
当模数 mᵢ 不互质时,标准 CRT 不再适用。此时需要两两合并方程。思路是:
假设已有方程 x ≡ r1 (mod m1) 和 x ≡ r2 (mod m2),我们设 x = r1 + t·m1,代入第二个方程得到: