1、一般地,中国余数定理是指若有一些两两互质的整数,则对于任意的整数: ,以下联立同余方程组对模有公解:
x ≡ (mod ) (1)
x ≡ (mod ) (2)
:
:
x ≡ (mod ) (n)
还是用经典的例子解释吧:
今有物不知其数,三三数之剩二,五五数之剩三,七七数之盛二,问物几何?答曰:廿三。
设x是所求物数,则依题意 x=2(mod 3),x=3(mod 5),x=2(mod 7)。计算方法如下
除数 | 余数 | 最小公倍数 | 衍数 | 乘率 | 各总 | 答数 | 最小答数 |
3 | 2 | 3*5*7= 105 | 5*7 | 2 | 35*2*2 | 140+63+30= 233 | 233%105=23 |
5 | 3 | 3*7 | 1 | 21*1*3 | |||
7 | 2 | 3*5 | 1 | 15*1*2 |
秦九韶将称为定数,将它们的总乘积M=称为衍母,再将衍母除以各个定数所得到的商: 称为衍数。接下来他将满足 ≡ 1 (mod )的正整数称为乘率。
这些量的几算方法如下://div[N]里边已经存好了除数
for(i=0;i<n;i++) M* = div[i]; //M为最小公倍数,这里只考虑除数两两互素的情况
for(i=0;i<n;i++) yanshu[i] = M/div[i]; //衍数的计算
for(i=0;i<n;i++) //乘率的计算,比较麻烦一些
{
for(j = yanshu[i]/div[i]; (j*div[i] +1)%yanshu[i];j++);
chenglv[i] = (j*div[i]+1)/yanshu[i];
}
下边是比较正统的中国余数定理代码:
int extgcd(int a, int b, int & x, int& y)
{
if (b==0)
{ x=1; y=0; return a; }
int d = extgcd(b, a%b, x, y);
int t = x; x = y; y = t - a / b * y;
return d;
}
int china(int b[], int w[], int k)
{
inti, d, x, y, m, a = 0, n = 1;
for(i = 0; i < k; i++) n *= w[i];
for(i = 0; i < k; i++)
{
m= n / w[i];
d= extgcd(w[i], m, x, y);
a= (a + y * m * b[i]) % n;
}
if (a > 0) return a;
else return (a + n);
}
中国余数定理主要有两个主要作用。
设整数n因式分解为:n=n1*n2*...*nk,其中ni两两互质。首先,中国余数定理是一个描述性的“结构定理”,它说明Zn的结构等同与笛卡尔积的结构,其中,第i个组元定理了对模ni的组元之间的加法与乘法运算。其次,用这种描述常常可以获得有效的算法,因为处理系统中的每个系统可能比处理模n运算效率更高(从位操作次数看)。