同余方程(组)、中国剩余定理(CRT、EXCRT)
同余方程
求出\(ax\equiv b \pmod p\)的解。
首先根据裴蜀定理必须要有\((a,p)\mid b\),要不然无解。如果\((a,p)=1\),显然\(a\)存在逆元,则\(x \equiv ba^{-1} \pmod p\);
如果\((a,p)\neq 1\),令\(d=(a,p)\),
令\(a'=\frac{a}{d}\),\(b'=\frac{b}{d}\),\(p'=\frac{p}{d}\),此时有\((a', p')=1\),\(a'\)存在逆元,所以\(x \equiv b'a'^{-1} \pmod {p'}\)。如果逆元不能用费马定理求解(比如说\(p'\)不是质数),就用\(\text{Ex-GCD}\)求解。一般也就用这个方法求。
对于同余方程组呢?比如说求解
这里需要用到中国剩余定理(CRT)了。
解法一:构造
让\(M=\prod p_i\),\(m_i = \frac{M}{p_i}\),令\(m_i^{-1}\)为\(m_i\)在模\(p_i\)意义下的逆元,则有\(m_im_i^{-1} \equiv 1 \pmod {p_i}\),即\(a_im_im_i^{-1} \equiv a_i \pmod {p_i}\),将\(a_im_im_i^{-1}\)记作\(L_i\)。这里可以看出\(m_i^{-1}\)的存在必须满足:\((m_i,p_i)=1\),也就是\(p_i\)两两互质才行。
构造\(x=\sum L_i\),\(x \bmod M\)就是同余方程组的最小正整数解。
\(\forall i,j:L_j \bmod p_i \equiv \begin{cases} 0,j \neq i(m_i中有因子p_i)\\ a_i,j=i(由上面定义可知)\end{cases}\)
ll crt(int n) {
ll M = 1, ans = 0;
rep(i, 1, n) M *= b[i];
rep(i, 1, n) {
ll x, y, d = exgcd(m[i] = M/b[i], b[i], x, y);
ans = (ans+1ll*a[i]*m[i]*x) % M; // 上文公式
}
return ans < 0 ? ans+M : ans; // 答案为正数
}
构造的局限性也很显然:模数要两两互质才行,否则无法构造。
复杂度:\(\mathcal O(n\log (\prod p_i))\),因为要求逆。
解法二:合并
又称扩展中国剩余定理(EXCRT)。
构造可以应用于各种情形(不互质也ok)。思想就是将两个同余式合并成一个同余式,合并\(n-1\)次只剩下一个同余式,就是我们要的答案。
令\(k_i=\text{LCM}_{x\leq i}\ p_x\),假设我们合并了前面的\(i-1\)个方程,通解为\(x\),也就是说这个\(x\)代入前\(i-1\)个方程恒成立,为了让第\(i\)个方程成立,我们有:
记\(x'=x+t\times k_{i-1}\),发现\(x'\)对于前\(i\)个式子恒成立,而且\(k_{i-1}\)与前\(i-1\)个模数取余为\(0\)。解出来\(t\),然后一直算下去。
但是不互质时可能会无解,当且仅当\((k_{i-1}, p_i)\nmid a_i-x\)。
// 变量有所区别
ll excrt(int n) {
ll lcm = 1, ans = 0; // lcm为前i个数的最小公倍数,ans为答案
rep(i, 1, n) {
ll x, y, d = exgcd(lcm, b[i], x, y); // 求解约分后的同余方程,其中x为解,d为最大公约数
if ((a[i]-ans) % d) return -1; // 判断原来的同余方程是否有解
ll t = b[i]/d; // 约分后的b
x = x * (a[i]-ans)/d % t; // 还原x的解
ans += x * lcm; ans %= (lcm *= t); // 合并结果,维护lcm
}
return ans < 0 ? ans+lcm : ans; // 注意答案要为正数
}
// 注意中间乘积和取模可能会溢出,需要用玄学快速乘
复杂度\(\mathcal O(n\log(\text{LCM}_{1\leqslant i\leqslant n}p_i))\)。