能用中国剩余定理(Chinese Remainder Theorem, CRT)合并互质同余,用扩展 CRT(exCRT)处理非互质模数,判断无解并控制乘法溢出。
前置:gcd、扩展欧几里得、模逆、线性同余。
已合并为
$$ x\equiv r\pmod M, $$
再加入 $x\equiv b\pmod m$。令 $x=r+Mt$,得到
$$ Mt\equiv b-r\pmod m. $$
设 $g=\gcd(M,m)$。若 $g\nmid(b-r)$ 无解;否则约去 $g$,M/g 在模 m/g 下可逆,求出最小非负 t。新余数为 r+M*t,新模数为 lcm(M,m),再规范化余数。
这就是 exCRT:逐条合并,不要求模数两两互质。
M*t 可能超过 64 位;题目未保证安全时用 __int128 做中间乘法。互质 CRT 给出模 21252 的唯一解类。合并余数 r 后,答案是 (r-d) mod 21252,若结果为 0 则取 21252,因为题目要求未来而非当天。CRT 唯一性保证该正代表是下一次而非某次更晚相遇。
r, period = CRT([(p,23), (e,28), (i,33)])
days = (r - d) mod period
if days == 0: days = period
x ≡ remainder (mod modulus),模数不保证互质,求最小非负解或 -1。(r,M) 完整代表此前所有方程,不需保存旧式子。初始 (0,1) 表示所有整数。逐条代入 x=r+Mt 解线性同余;若兼容则得到所有共同解的唯一剩余类,更新为规范化的 (r,lcm)。归纳可知处理 k 条后恰表示前 k 条共同解集;最终 r 是最小非负解。每次 $O(\log\max modulus)$。
r, M = 0, 1
for (modulus m, remainder b):
g, inverse = extended_gcd(M, m)
if (b-r) is not divisible by g: return -1
t = ((b-r)/g * inverse) mod (m/g)
r = r + M*t
M = lcm(M,m); r %= M
(S+Kx) mod N = 0,无解输出 -1。线性同余有解当且仅当 g 整除 S。约分后 K/g 与 N/g 互质,其逆元存在;乘到右侧并规范化就得到模 N/g 的唯一解类,最小非负代表即答案。每组 $O(\log N)$。
g = gcd(K,N)
if S % g != 0: answer = -1
else:
K,N,S = K/g,N/g,S/g
answer = (-S * inverse(K mod N)) mod N
CRT 解决的是多个同一未知量的同余交集;高斯消元解决多个未知量的线性系统。模数不是质数时,多变量系统可考虑质因数分解后分别求解再 CRT,但素数幂上的消元仍需处理非单位主元。
枚举小模数所有 x 对拍 exCRT,覆盖兼容非互质、不兼容、某模数整除另一模数。用接近 $10^{18}$ 的数检查中间乘法是否需要 128 位。