首先我们还是从简单入手,考虑一下如果同余方程组只有两个式子的情况
x≡c1(mod m1)
x≡c2(mod m2)
将两个式子变形
x=c1+m1k1
x=c2+m2k2
联立
c1+m1k1=c2+m2k2
移项
m1k1=c2−c1+m2k2
我们用GCD(a,b)表示a,b的最大公约数
在这里需要注意,这个方程有解的条件是
GCD(m1,m2)|(c2−c1),因为后面会用到(c2−c1)/(m2,m1)这一项,如果不整除的话肯定会出现小数。
推广一下
我们每次把两个同余式合并,求解之后得到一个新的同余式。再把新的同余式和其他的联立,最终就可以求出满足条件的解
题目: https://ac.nowcoder.com/acm/contest/75/B
代码:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include<bits/stdc++.h> 2 using namespace std; 3 ll a[100003],b[100003]; 4 ll t; 5 void ex(ll x1,ll y1,ll &d,ll &x,ll &y) 6 { 7 if(y1==0) 8 { 9 d=x1; 10 x=1; 11 y=0; 12 return ; 13 } 14 ex(y1,x1%y1,d,y,x); 15 y-=x1/y1*x; 16 } 17 ll china() 18 { 19 ll m1=a[1]; 20 ll r1=b[1]; 21 for(ll i=2;i<=t;i++) 22 { 23 ll m2=a[i]; 24 ll r2=b[i]; 25 ll x,y,d; 26 ex(m1,m2,d,x,y); 27 ll r=r2-r1; 28 if(r%d)return -1; 29 ll t=m2/d; 30 x=(x*r/d%t+t)%t; 31 r1=x*m1+r1; 32 m1=m1*m2/d; 33 } 34 if(1==t&&r1==0)return m1; 35 return r1; 36 } 37 int main() 38 { 39 cin>>t; 40 for(ll i=1;i<=t;i++) 41 { 42 cin>>a[i]>>b[i]; 43 } 44 cout<<china()<<endl; 45 }