中国剩余定理又称孙子定理, 主要是为了解线同余方程组
- x ≡ a1 ( mod m1 )
- x ≡ a2 ( mod m2 )
- x ≡ a3 ( mod m3 )
- .........
- x ≡ an ( mod mn )
成立条件是m1,m2, ... ,mn 两两互质, 则对任意的整数:a1,a2, ... ,an,方程组S 有解
并且可以构造出通解 x = ( a1*t1*M1 + a2*t2*M2 + a3*t3*M3 +...+ an*tn*Mn ) + KM
在模M的意义下 x = ( a1*t1*M1 + a2*t2*M2 + a3*t3*M3 +...+ an*tn*Mn )
M = m1 * m2 * m3 * ... * mn ,
Mi = M / mi
t
i
为
M
i
模
m
i
显然带入方程组中可验证正确性,证明略
//非递归的扩展欧几里德算法
//返回a、b的gcd,同时x、y满足ax+by=gcd
int_t _exEuclid(int_t a,int_t b,int_t&x,int_t&y){
int_t x0 = 1, y0 = 0;
int_t x1 = 0, y1 = 1;
x = 0; y = 1;
int_t r = a % b;
int_t q = ( a - r ) / b;
while( r ){
x = x0 - q * x1;
y = y0 - q * y1;
x0 = x1; y0 = y1;
x1 = x; y1 = y;
a = b; b = r; r = a % b;
q = ( a - r ) / b;
}
return b;
}
//求a相对于p的逆元,a、p互质才存在逆元
int_t _inv(int_t a,int_t p){
int_t x,y;
int_t r = _exEuclid(a,p,x,y);
if ( r != 1 ) return 0;
x = x % p;
if ( x < 0 ) x += p;
return x;
}
// 中国剩余定理
int_t CRT( int n ,int_t *remain, int_t *mod){
int_t M = 1, x = 0;
for (int i = 0;i < n;++i)
M *= mod[i];
for ( int i = 0;i < n;++i ){
M /= mod[i];
x += remain[i] * M * _inv(M,mod[i]) ;
M *= mod[i];
}
return x;
}