题意:https://www.luogu.org/problemnew/solution/P4777
解题思路:关于扩展中国剩余定理推导,看我其他的博客。
#include<bits/stdc++.h>
#define N 100009
#define ll long long
using namespace std;
ll a[N],b[N];
int n;
/*该方程 用于以下形式
x=b1(mod a1)
x=b2(mod a2)
......
x=bn(mod an)*/
ll ex_gcd(ll a,ll b,ll &x,ll &y)
{
if(b==0){x=1,y=0;return a;}
ll r=ex_gcd(b,a%b,y,x);
y-=x*(a/b);
return r;
}
/*ll ex_crt()
{
ll M=a[0],R=b[0],x,y,d;//a是除数,也是答案 。b是被除的
for(int i=1;i<n;i++)
{
d=ex_gcd(M,a[i],x,y);
if((b[i]-R)%d) return -1;//无解
x=(b[i]-R)/d*x%(a[i]/d);//计算系数
R+=x*M;//计算新X1的a,即特解
M=M/d*a[i];//LCM新的最小公倍数
R%=M;//由方程的原始形式可知,可以这么做。而且可以减小数字大小
}
return R>0? R: R+M;
}*/
ll mul(ll x,ll y,ll mod)
{
ll ans=0,res=x;
while(y)
{
if(y&1) ans=(ans+res)%mod;
y>>=1;
res=(res+res)%mod;
}
return ans;
}
ll ex_crt()
{
ll M=a[0],R=b[0],x,y,d;//a是除数,也是答案 。b是被除的
for(int i=1;i<n;i++)
{
d=ex_gcd(M,a[i],x,y);
ll c=((b[i]-R)%a[i]+a[i])%a[i];//其实就是扩大b[i],让b[i]>R.b[i]=b[i]+k*a[i]
if(c%d) return -1;//无解
x=mul(x,c/d,a[i]/d);
R+=x*M;//计算新X1的a,即特解
M=M/d*a[i];//LCM新的最小公倍数
R%=M;//由方程的原始形式可知,可以这么做。而且可以减小数字大小
}
return R>0? R: R+M;
}
int main()
{
//freopen("t.txt","r",stdin);
scanf("%d",&n);
for(int i=0;i<n;i++)
{
scanf("%lld%lld",&a[i],&b[i]);
}
printf("%lld",ex_crt());
return 0;
}