「数论学习笔记」#1 扩展中国剩余定理

中国剩余定理(CRT)

由于扩展中国剩余定理和中国剩余定理没啥关系,所以我们先来复习一下中国剩余定理。

同余方程组 \[ \begin{cases} x \equiv a_1 \pmod {m_1} \\ x \equiv a_2 \pmod {m_2} \\ \quad \vdots \\ x \equiv a_n \pmod {m_n} \end{cases} \]\(m_1,m_2,\cdots ,m_n\) 两两互质时,对于任意正整数 \(a_1,a_2,\cdots,a_n\),此方程组有解,如下。

\(M = \prod_{i=1}^n m_i\)\(M_i = \frac{M_i}{m_i}\)

\(t_i = M_i^{-1}\),在 \(\bmod m_i\) 的意义下。

那么方程组的通解为 \(x = kM + \sum_{i=1}^n a_i t_i M_i\),其中 \(k \in \mathbb{Z}\)

最小正整数解只要令 \(k=0\),后面那一块对 \(M\) 取模即可。

代码

MM=1;
for(int i=1;i<=n;++i) MM*=m[i];
for(int i=1;i<=n;++i) {
    M[i]=MM/m[i];
    int x, y;
    exgcd(M[i],m[i],x,y);
    t[i]=x;
    ans=(ans+a[i]*M[i]*t[i]%MM)%MM
}
ans=(ans%MM+MM)%MM;

证明略。

扩展中国剩余定理(exCRT)

\(m_1,m_2,\cdots m_n\) 不满足两两互质时,就要用到扩展中国剩余定理了。

考虑 \[ \begin{cases} x \equiv a_1 \pmod {m_1} \\ x \equiv a_2 \pmod {m_2} \end{cases} \] 转化一下 \[ \begin{cases} x = k_1 m_1 + a_1 \\ x = k_2 m_2 + a_2 \end{cases} \]

\[ k_1 m_1 - k_2 m_2 = a_1 - a_2 \]

注意到此方程有解,当且仅当 \(\gcd(m_1,m_2) \mid a_1-a_2\)

\(g=\gcd(m_1,m_2)\)\(p_1 = \frac{m_1}{g}\)\(p_2 = \frac{m_2}{g}\),代入得 \[ k_1 p_1 - k_2 p_2 = \frac{a_1-a_2}{g} \] 由于 \(\gcd(p_1,p_2)=1\),此方程有解当且仅当 \(1 \mid \frac{a_1 - a_2}{g}\)。那么一定有 \(g \mid a_1 - a_2\),否则无解。

那么先求出一组特解 \[ p_1 x_1 + p_2 x_2 = 1 \] 得到 \[ \begin{cases} k_1 = \frac{a_2-a_1}{g} x_1 \\ k_2 = \frac{a_2-a_1}{g} x_2 \end{cases} \] 代入原式 \[ x = k_1 m_1 + a_1 = \frac{a_2 - a_1}{g}x_1 m_1 + a_1 \] 至此,得到一个解。

不妨称同余号右边的数为“同余数”。

考虑数论里一个结论,若 \(a \equiv b \pmod {m_i}\),其中 \(i \in [1,n]\),则 \[ a \equiv b \pmod {\operatorname{lcm}\{m_1,m_2,\cdots ,m_n\}} \] 因此,求出两个方程的解时,只要模数取原来两个模数的最小公倍数,就能将原来两个方程合并成一个方程。

且慢,不是还要求同余数相等吗?令他为 \(xm_1 + a_1\) 即可,虽然我也不知道为什么

设当前同余数为 \(R\)\(M\)\(m_1,m_2,\cdots,m_{i-1}\) 的最小公倍数,则对于一个新的方程组 \[ \begin{cases} x \equiv R \pmod M \\ x \equiv a_i \pmod {m_i} \end{cases} \] 再次求解即可。

代码

void exCRT() {
	M=m[1], R=r[1];
    // m[]是模数,r[]是同余数
	for(int i=2;i<=n;++i) {
		int d=r[i]-R, g, mod, x, y;
		g=exgcd(M,m[i],x,y);
        // 这里求解的是 Mx+m[i]y=gcd(M,m[i])
        // 根据等式的性质,易得等价于上文中的 p1x1+p2x2=1
		if(d%g) { ans=-1; return; }
        // 无解
		mod=m[i]/g;
        // 取模是因为要求最小正整数解,mod为什么这样算详见exgcd
		x=((x*d/g)%mod+mod)%mod;
        // 解
		R=x*M+R;
        // 更新R
		M=(M*m[i])/g;
        // M取lcm
	}
	ans=R;
    // 答案
}

 

参考:


「数论学习笔记」#1 扩展中国剩余定理
https://yozora0908.github.io/2022/notes-number-theory-1/
作者
yozora0908
发布于
2022年7月29日
许可协议