注:此文章适合有一定数论基础的同学阅读...
神牛解释来源: http://blog.sina.com.cn/s/blog_93ced90c0101716k.html
中国剩余定理要求n = n1 * n2 * ... * nk中所有的数要两两互质,那么当给出的数据不是两两互质时要怎么处理呢?
为什么中国剩余定理要求n1,n2,...,nk两两互质呢?
因为这样就可以保证mi = n/ni必然和ni是互质的.
这样就有一个好处,就是mi%nj == 0(i != j);也就是说当用mi和除ni外的任何nj做模运算都将会等于0.
ci = mi*(mi^-1mod ni)具有这样的性质,ci % ni == 1;ci % nj == 0;
上式成立条件补充一点:mi*(mi^-1)%ni = mi%ni * (mi^-1)%ni=1
如果用坐标的形式从取模意义上来表示的话,ci可以表示成为(0,0,0,...1,0,0,0...);
用ai与ci相乘的结果模ni,将仍然得到ai.
如果说要求一个数a,已知 a mod n1 = a1, a
那么a = a1*c1+a2*c2必然是满足要求的,因为a mod n1 = a1, a mod n2 =a2;
补充:由上面的解释知道 n1 | c2 , n2|c1; 所以必然是满足要求的
如果还要求a mod n3 = a3呢?
很简单 a = a1*c1 +a2*c2 +a3*c3.
一个原理,要让a mod ni = ai,只要让a加上对应的ai*ci就可以了,这就好像打补丁一样,缺什么就补什么,而且打什么补丁并不会相互影响.
当然以上性质都是在n1,n2,...nk两两互质的情况下才成立的.
如果遇到n1,n2,...,nk不能够保证两两互质的情况要怎么处理呢?
一种可能的思路是,先解出满足x mod n1
加入ai时,将a1,a2,...,ai-1都看成一个整体,这样我们每次都是在处理2个模线性方程,它们构成了一个模线性方程组.
现在的问题是如何解决由两个模线性方程组成的方程组?
求解单个的模线性方程是有固定的算法可以解决.
例如:
x mod n1 = a1
x mod n2 = a2
求出满足条件的x的值.
由第一个方程可以解出x = a1+k1*n1;
代入第二个方程,得到a1+k1*n1 = a2 +k2*n2;
整理得,a1 - a2 = k2*n2 - k1*n1;
两边同时mod n2,得到(a2 - a1)mod n2 =( k1*n1) mod n2.
或者也可以写成n1*k1(mod n2) = (a2 - a1)mod n2.
只要解出k1代到①式中就可以了.
问题是k1怎么求?
把k1看成是变量,可以得到一个模线性方程n1*x =(a2 - a1)mod n2;
这是一个模线性方程,我们可以运用求解模线性方程的方法来求解.
x0 = x'(a2 - a1)/d(mod n2)
d = gcd(n1,n2);
其中x‘满足d = x'*n1+y'*n2;可以用扩展欧几里德算法求出x';
所以x0是第二个方程的解,而且是最小解.
第二个方程的通解形式为x = x0 +k(n2/d);(0 <= k <=d -1)
也就是k1 = x0+k(n2/d);(0<= k <= d-1)
代入第一个方程中,得到x = a1+k1*n1 = a1 +(xo + k(n2/d))*n1 = a1 + x0*n1 + k*(n2/d)*n1
所以x = (a1 + x0*n1) mod(n1*n2/d);
这样子一直扩展下去最可以求出满足所有条件的x的值.
详细资料参考来源:http://yzmduncan.iteye.com/blog/1323599