题解:
x = ai ( mod mi ) 1 <= i <= k
先考虑k==2的情况:
x = a1 ( mod m1 )
x = a2 ( mod m2 )
方程组有解的充分必要条件是: d | (a1-a2) ,其中 d = (m1,m2)
证明如下:
必要性: 设 x 是上面同余方程组的解,从而存在整数q1,q2使得x=a1+m1*q1,x=a2+m2*q2,消去x即得a1-a2 = m2q2-m1q1。由于d=(m1,m2),故d | (a1-a2)。
充分性:若d=(m1,m2) | (a1-a2)成立,则方程m1*x + m2*y = a1-a2有解。
设解为x0,y0。那么m2*y0 = a1-a2 ( mod m1 )
记x1 = a2+m2*y0,可以知道 x1=a2 ( mod m2 ),且x1 = a2+m2*y0 = a2 + ( a1-a2) = a1 ( mod m1 )
所以 x1 = a2 ( mod m2 ) = a1 ( mod m1 )
所以 x = x1 ( mod [m1,m2] )
另外,若x1与x2都是上面同余方程组的解,则 x1 = x2 ( mod m1 ), x1 = x2 ( mod m2 ), 由同余的性质得 x1 = x2 ( mod [m1,m2] ),即对于模[m1,m2],同余方程组的解释唯一的。
证毕。
····
k>2的情形。略。
#include<cstdio>
#define lint __int64
lint Egcd ( lint a, lint b, lint &x, lint &y )
{
lint tmp, ret;
if ( b == 0 )
{
x = 1, y = 0;
return a;
}
ret = Egcd ( b, a % b, x, y );
tmp = x, x = y, y = tmp-a/b*y;
return ret;
}
lint gcd ( lint a, lint b )
{
if ( b == 0 )
return a;
return gcd ( b, a % b );
}
//求模线性方程组 ax = b ( mod m )
lint modular_linear ( lint a, lint b, lint m )
{
lint d, x, y;
d = Egcd ( a, m, x, y );
if ( b % d != 0 ) return -1; // 无解则返回-1。
return ( x * (b/d) % m + m ) % m;
}
int main()
{
lint a1, a2, m1, m2, k, y;
while ( scanf("%I64d",&k) != EOF )
{
bool flag = false;
scanf("%I64d%I64d",&m1,&a1);
if ( k == 1 ) y = a1;
for ( int i = 1; i < k; i++ )
{
scanf("%I64d%I64d",&m2,&a2);
if ( flag ) continue;
lint y = modular_linear ( m2, a1 - a2, m1 );
if ( y == -1 ) { flag = true; continue; }
a1 = a2 + m2 * y;
m1 = m1*m2/gcd(m1,m2);
a1 = ( a1 % m1 + m1 ) % m1;
}
if ( flag ) printf("-1\n");
else printf("%I64d\n",a1);
}
return 0;
}