前面我们已经学习了求解单个线性模方程,如果有多个方程,变量还是只有一个,该怎么办呢?
可以考虑用中国剩余定理(Chinese Remainder Theorem)。假定有方程组$xequiv a_i(mod m_i)$,且所有模$m_i$两两互素。令$M$为所有$m_i$的乘积,$w_i=M/m_i$,则$(w_i,mi)=1$。用扩展欧几里得算法可以找到$p_i$和$q_i$使得$w_i p_i + m_i q_i = 1$。然后令$e_i = w_i p_i$,则方程组等价于单个方程$xequiv e_1 a_1 + e_2 a_2 + cdots + e_n a_n(mod M)$.换句话说,在模M的剩余系下,原方程组有唯一解。
不难验证$x= e_1 a_1 + e_2 a_2 + cdots + e_n a_n$是一个解(具体见拉格朗日插值法),把等式$w_i p_i + m_i q_i = 1$两边模$m_i$后立即可得到$e_i mod m_i = 1$,而对于不等于$i$的$j$,$w_i$是$m_j$的倍数(想一想,为什么),因此$e_i mod m_j = 0$。这样,$x_0$对$m_i$取模时,除了$e_i a_i$这一项余数为$ 1 imes a_i = a_i$之外,其余项的余数均为0.代码如下:
//n个方程:x=a[i](mod m[i]) ll china(int n, int* a, int* m) { ll M = 1, d, y, x = 0; for (int i = 0; i < n; i++) M *= m[i]; for (int i = 0; i < n; i++) { ll w = M / m[i]; exgcd(m[i], w, d, d, y); //d共用了 x = (x + y * w * a[i]) % M; //x相当于sum } return (x + M) % M; }