中国剩余定理&扩展中国剩余定理

创建时间:2025-05-28


中国剩余定理

中国剩余定理(Chinese Remainder Theorem,CRT),是数论中的重要定理,但使用场景很有限,且复杂度也只是与扩展中国剩余定理持平,故在OI赛场上用的很少,只需要掌握扩展中国剩余定理即可。当然,中国剩余定理的原理也值得了解。

给定 \(n\) 个形如 \(x \equiv b_i \pmod m_i\) 的方程(\(m_i\) 两两互质),中国剩余定理可以在 \(O(n \log n)\) 的时间内求出 \(x\) 的最小非负数解。

可以考虑先解出这 \(n\) 个同于方程组的解:

\[\begin{cases} x_1\equiv b_1\pmod {m_1} \\x_1\equiv 0\pmod {m_2}\\ \cdots\\ x_1\equiv 0\pmod {m_n}\\ \end{cases} \begin{cases} x_2\equiv 0\pmod {m_1}\\ x_2\equiv b_2\pmod {m_2}\\ \cdots\\ x_2\equiv 0\pmod {m_n}\\ \end{cases} \cdots \begin{cases} x_n\equiv 0\pmod {m_1}\\ x_n\equiv 0\pmod {m_2}\\ \cdots\\ x_n\equiv b_n\pmod {m_n}\\ \end{cases} \]

\(x=\sum x_i\),则 \(x\) 满足

\[\begin{cases} x \equiv \sum x_i \equiv b_1 \pmod {m_1}\\ x \equiv \sum x_i \equiv b_2 \pmod {m_2}\\ \cdots \\ x \equiv \sum x_i \equiv b_n \pmod {m_n}\\ \end{cases} \]

所以 \(x=\sum x_i\) 就是我们原同于方程组的解,至于最小非负整数解,根据同于方程的解的周期性,它就等于 \(x \bmod \textup{lcm}(m_1,m_2,\cdots,m_n)=x \bmod \Pi m_i\)

接下来考虑怎么解这个方程组:

\[\begin{cases} x_i\equiv 0\pmod {m_1} \\x_i\equiv 0\pmod {m_2}\\ \cdots\\ x_i\equiv 0\pmod {m_{i-1}}\\ x_i\equiv b_i\pmod {m_i}\\ x_i\equiv 0\pmod {m_{i+1}}\\ \cdots\\ x_i\equiv 0\pmod {m_n}\\ \end{cases} \]

由于 \(x_i\)\(m_1,m_2,\cdots,m_{i-1},m_{i+1},\cdots,m_n\) 的倍数,所以 \(x_i\) 一定可以写作 \(k \cdot \textup{lcm}(m_1,m_2,\cdots,m_{i-1},m_{i+1},\cdots,m_n)=k_i \frac {\Pi m_j} {m_i}\),于是 \(k_i \frac {\Pi m_j} {m_i} \equiv b_i \pmod {m_i}\),这个方程我们就熟悉了,令 \(k_i\equiv (\frac {\Pi m_j} {m_i})^{-1}b_i \pmod {m_i}\) 即可,故 \(x_i\equiv \frac {\Pi m_j} {m_i} {m_i}^{-1}b_i \pmod {m_i}\)。最终答案 \(x=\sum \frac {\Pi m_j} {m_i} {m_i}^{-1}b_i \bmod \Pi m_j\)

代码:

int exgcd(int a, int b, int& x, int& y) {
    if (b == 0) {
        x = 1, y = 0;
        return a;
    }
    int x0, y0, d = exgcd(b, a % b, x0, y0);
    x = y0, y = x0 - a / b * y0;
    return d;
}

int CRT(int n, const int m[], const int b[]) {
    int M = 1, ans = 0;
    for (int i = 1; i <= n; i++)
        M *= m[i];
    for (int i = 1; i <= n; i++) {
        int x, y, d = exgcd(M / m[i], m[i], x, y);
        ans = (ans + M / m[i] * x % M * b[i]) % M;
    }
    return (ans + M) % M;
}

扩展中国剩余定理

扩展中国剩余定理(extended Chinese Remainder Theorem,exCRT)可以在 \(m_i\) 不两两互质的情况下求解同于方程,它的本质其实是递推+扩展欧几里得算法。

我们先考虑前 \(i\) 个式子,设 \(ans\) 为前 \(i\) 个式子的最小非负整数解,\(lcm\) 为前 \(m_1,m_2,...,m_i\) 的最小公倍数。由同余方程周期性知前 \(i-1\) 个通解为 \(ans + k \cdot lcm(k \in \N)\),要使第 \(i\) 个同于方程成立,则要求出最小的非负整数 \(x\) 使 \(ans+x \cdot lcm \equiv b_i (\bmod m_i)\),即 \(x \cdot lcm \equiv b_i-ans(\bmod m_i)\)。这个式子我们很熟悉,第一时间就能想到用扩展欧几里得求解该式的变形(\(lcm \cdot x + m_i \cdot y = b_i-ans\))的最小非负整数解,并更新 \(ans \leftarrow ans+x \cdot lcm\)\(lcm \leftarrow \frac {lcm \cdot m_i} d\)

考虑该递推式的初始状态,即 \(i=0\)\(ans\)\(lcm\) 的值,显然此时解没有任何限制,故 \(ans \leftarrow 0\)\(lcm \leftarrow 1\)

参考代码:

int exgcd(int a, int b, int& x, int& y) {
	if (b == 0) {
		x = 1, y = 0;
		return a; 
	}
	int x0, y0, d = exgcd(b, a % b, x0, y0);
	x = y0, y = x0 - a / b * y0;
	return d;
}

int exCRT(int n, const int m[], const int b[]) {
	int ans = 0, lcm = 1;
	for (int i = 1; i <= n; i++) {
		int c = ((b[i] - ans) % m[i] + m[i]) % m[i];
		int x, y, d = exgcd(lcm, m[i], x, y);
		if (c % d)
			return -1;
		int p = m[i] / d;
		x = (x * (c / d) % p + p) % p;
		ans += x * lcm, lcm *= m[i] / d;
	}
	return ans;
}

中国剩余定理&扩展中国剩余定理的应用

P1495 【模板】中国剩余定理(CRT)/ 曹冲养猪
P4777 【模板】扩展中国剩余定理(EXCRT);
P4774 [NOI2018] 屠龙勇士(平衡树+扩展中国剩余定理)
P4621 [COCI 2012/2013 #6] BAKTERIJE(模拟+枚举+扩展中国剩余定理)
P2480 [SDOI2010] 古代猪文(欧拉定理+质因数+卢卡斯定理+中国剩余定理)

posted @ 2026-05-19 12:35  xubaichuan  阅读(24)  评论(0)    收藏  举报