poj 2891
这道题就是中国剩余定理(非互质)模板题,定理的相关内容在hdu 5446里。
参考链接:http://yzmduncan.iteye.com/blog/1323599
#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; }