这道题就是中国剩余定理(非互质)模板题,定理的相关内容在hdu 5446里。
参考链接:http://yzmduncan.iteye.com/blog/1323599
2015.10.30:
(那美好的仗我已经打完了,应行的路我已经行尽了,当守的道我守住了。 从此以后,有公义的冠冕为你留存。
The good fight, I have finished, should do the road I have done, when his faith I hold on to. From now on, the crown of righteousness has retained for you.
——江南 《龙族3·黑月之潮》
)
#include<stdio.h>
#include<string.h>
#include<iostream>
using namespace std;
#define N 200010
long long int a[N];
long long int b[N];
long long int gcd(long long int x,long long int y){
long long int z;
while(y){
z=x%y;
x=y;
y=z;
}
return x;
}
void exgcd(long long int *m,long long int *n,long long int x,long long int y){
if(!y){
*m=1;
*n=1;
}
else{
long long int tempm,tempn;
exgcd(&tempm,&tempn,y,x%y);
*m=tempn;
*n=tempm-x/y*tempn;
}
return;
}
long long int inv(long long int x,long long int y){
/*long long int tempy=y-2;//不能直接求x^(y-2)次方,因为x虽然与y互质,但是并不代表这y一定是质数,这种方法,只能用于y是质数的时候
long long int ans=1;
while(tempy){
if(tempy%2){
ans=ans*x%y;
}
tempy=tempy/2;
x=x*x%y;
}
return ans;*/
long long int m,n;
exgcd(&m,&n,x,y);
m=(m%y+y)%y;
return m;
}
void merge(int x,int y){
long long int c=b[y]-b[x];//有可能是负数
long long int d=gcd(a[x],a[y]);
long long int n1=a[x],n2=a[y],a1=b[x],a2=b[y];//这里余数和模数弄反了
if(c%d){
b[y]=-1;
}
else{
c=(c%n2+n2)%n2;
c=c/d;
n1=n1/d;
n2=n2/d;
c=c*inv(n1,n2);
c=c%n2;
c=(c*n1%(n2*n1*d)*d%(n2*n1*d)+a1)%(n2*n1*d);
b[y]=c;
a[y]=n1*n2*d;
}
return;
}
long long int China_Reminder(int k){
for(int i=0;i<k-1;i++){
merge(i,i+1);
if(b[i+1]==-1){
b[k-1]=-1;
break;
}
}
return b[k-1];
}
int main(){
int k;
while(scanf("%d",&k)!=EOF){
for(int i=0;i<k;i++){
scanf("%lld%lld",&a[i],&b[i]);
}
printf("%lld\n",China_Reminder(k));
}
return 0;
}