传送门:https://ac.nowcoder.com/acm/problem/15068
题目描述:
uu遇到了一个小问题,可是他不想答。你能替他解决这个问题吗?
问题:给你k对a和r是否存在一个正整数x使每队a和r都满足:x mod a=r,求最小正解x或无解。
输入描述:
第一行是正整数k(k<=100000)
接下来k行,每行有俩个正整数a,r(100000>a>r>=0)
输出描述:
在每个测试用例输出非负整数m,占一行。
如果有多个可能的值,输出最小的值。
如果没有可能的值,则输出-1。
示例1输入:
2 8 7 11 9
示例1输出:
31
分析:
显然,是一道扩展中国剩余定理的模板题。
代码:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll MAXN=1e6+10;
ll K,C[MAXN],M[MAXN],x,y;
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 d=exgcd(b,a%b,x,y),tmp;
tmp=x;
x=y;
y=tmp-(a/b)*y;
return d;
}
ll inv(ll a, ll b) {
ll r=exgcd(a,b,x,y);
while (x<0) x+=b;
return x;
}
int main(){
int flag=1;
scanf("%lld",&K);
for(ll i=1;i<=K;i++)
scanf("%lld%lld",&M[i],&C[i]);
for(ll i=2;i<=K;i++) {
ll M1=M[i-1],M2=M[i],C2=C[i],C1=C[i-1],T=gcd(M1,M2);
if((C2-C1)%T!=0){
flag=0;
break;
}
M[i]=(M1*M2)/T;
C[i]=(inv(M1/T,M2/T)*(C2-C1)/T)%(M2/T)*M1+C1;
C[i]=(C[i]%M[i]+M[i])%M[i];
}
printf("%lld\n",flag?C[K]:-1);
return 0;
}