傳送門: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;
}