AcWing 204. 表达整数的奇怪方式
给定 2n 个整数 a1,a2,…,an 和 m1,m2,…,mn,求一个最小的非负整数 x,满足 ∀i∈[1,n],x≡mi(mod ai)。
输入格式
第 1 行包含整数 n。
第 2…n+1 行:每 i+1 行包含两个整数 ai 和 mi,数之间用空格隔开。
输出格式
输出最小非负整数 x,如果 x 不存在,则输出 −1。
如果存在 x,则数据保证 x 一定在 64 位整数范围内。
数据范围
1≤ai≤2^31−1,
0≤mi<ai
1≤n≤25
输入样例:
2
8 7
11 9
输出样例:
31
中国剩余定理的扩展

#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
LL exgcd(LL a,LL b,LL &x,LL &y){
if(b==0){
x=1,y=0;
return a;
}
else{
LL d=exgcd(b,a%b,y,x);
y-=a/b*x;
return d;
}
}
int main(){
int n;
bool has_answer=true;
LL a1,m1,a2,m2;
LL k1,k2;
cin>>n;
cin>>a1>>m1;
for(LL i=1;i<n;i++){
cin>>a2>>m2;
LL d=exgcd(a1,a2,k1,k2);
//cout<<d<<endl;
if((m2-m1)%d!=0){
has_answer=false;
break;
}
k1=((m2-m1)/d)*k1;
LL r=a2/d;
k1=(k1%r+r)%r;//剔除k1中能被r整除的部分,让k1尽可能小(也就是新的m1尽可能小),否则溢出
m1=a1*k1+m1;
a1=a1/d*a2;
}
if(!has_answer) cout<<-1;
else cout<<(m1%a1+a1)%a1;
return 0;
}

浙公网安备 33010602011771号