中国剩余定理是中国古代求解一次同余方程组的方法,是数论中的一个重要定理。
设m1,m2,m3,…,mk是两两互素的正整数,即gcd(mi,mj)=1,i!=j,i,j=1,2,3,…,k.
则同余方程组:
x = a1 (mod n1)
x = a2 (mod n2)
…
x = ak (mod nk)
模[n1,n2,…nk]有唯一解,即在[n1,n2,…,nk]的意义下,存在唯一的x,满足:
x = ai mod [n1,n2,…,nk], i=1,2,3,…,k。
解可以写为这种形式: x = sigma(ai* mi*mi’) mod(N)
其中N=n1*n2*…*nk,mi=N/ni,mi’为mi在模ni乘法下的逆元。
非互质版本采用方程合并的思想
//// Created by 王若璇 on 16/7/11.////中国剩余定理,非互质版本#include #include #include #include usingnamespacestd;
typedeflonglong ll;
ll gcd(ll a,ll b){
return b==0?a:gcd(b,a%b);
}
ll exgcd(ll a,ll b,ll &x,ll &y)
{
if(b==0)
{
x=1;
y=0;
return a;
}
ll r=exgcd(b,a%b,x,y);
ll t=x;
x=y;
y=t-a/b*y;
return r;
}
ll cal(ll a,ll m){
ll x,y;
ll r = exgcd(a,m,x,y);
if(1%r!=0){
return -1;
}
//x*=1/r;//m = abs(m);
ll ans = (x%m+m)%m;
//if(ans<=0) ans+=m;return ans;
}
bool merge(ll a1,ll r1,ll a2,ll r2,ll &aa,ll &rr){
ll d = gcd(a1,a2);
ll c = r2-r1;
if(c%d!=0){
returnfalse;
}
c = (c%a2+a2)%a2;
c/=d;
a1/=d;
a2/=d;
c*=cal(a1,a2);
c = c%a2;
c*=a1*d;
c+=r1;
aa = a1*a2*d;
rr = c;
returntrue;
}
int main(){
ios::sync_with_stdio(false);
cin.tie(NULL);
int n;
while (cin>>n){
ll k,m;
cin>>k>>m;
bool flag = true;
ll a,r,aa,rr;
for(int i = 1;icin>>a>>r;
if(flag&&merge(k,m,a,r,aa,rr)){
k = aa;
m = rr;
} else{
flag = false;
}
}
if(flag){
cout<<(rr%aa+aa)%aa<else{
cout<<-1<return 0;
}