之前的博客介绍了求解二元一次方程的方法-----扩展欧几里得
那如果要求解二元一次方程组的话,我们不可能每个进行一次EXGCD,取同解;
中国剩余定理就完美解决了这一问题;
中国剩余定理大致为:
若某数x分别被m1、、…、mn除得的余数为a1、a2、…、an,则可表示为下式:
x=R1a1+R2a2+…+Rnan其中 R1 是 d2 、 d3 、 … 、 dn 的公倍数,而且被 d1 除,余数为 1 ;(称为 R1 相对于 d1 的数论倒数)
R1 、
R2 、
… 、
Rn是d1、d2、…、dn-1的公倍数,而且被mn除,余数为1;
D是d1、d2、…、的最小公倍数;
R是任意整数(代表倍数),可根据实际需要决定;
且d1、、…、必须互质,以保证每个Ri(i=1,2,…,n)都能求得.
(注:因为R1对d1求余为1,所以R1r1对d1求余为r1,这就是为什么是R1对d1求余为1的目的,其次,R2r2,R3r3…Rnrn对d1求余都是0)
如上所示的x必为唯一解,因为对于这样的一个x分别%mi的时候,其余项均为0,本项R1a1%mi = 1 * ai = ai即为原解;
综上所述,我们要求解这样一个Rn,需要用到扩展欧几里得:
Rn * x = 1 (mod mi) --> Rn * x + mi * y = 1;
解出x之后,我们得到的就是Rn*x,这个数满足mod mi = 1,且与其他mi取余 == 0。
而最后的结果就是将这些x*Rn累加
中国剩余定理:
ll china(int n, int* a, int * m) {
int M = 1;
int 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];
exgdc(m[i], w, d, d, y); //两个都是d,原因待解
x = (x + y * w * a[i]) % M;
}
return M;
}