luoguP4777 【模板】扩展中国剩余定理(EXCRT)

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef __int128 i1;
ll k,a[100005],b[100005];
i1 xx,yy,ans,m;
inline void ex_gcd(i1 x,i1 y)
{
    if(!y){xx=1,yy=0;return;}
    ex_gcd(y,x%y); 
    i1 zz=xx; xx=yy; yy=zz-x/y*yy;
}
int main()
{
    scanf("%lld",&k);
    for(int i=1;i<=k;i++)scanf("%lld%lld",&b[i],&a[i]);
    ans=a[1];m=b[1];
    for(int i=2;i<=k;i++)
    {
        ex_gcd(m,(i1)b[i]);
        (xx*=(((a[i]-ans)%b[i]+b[i])%b[i])/__gcd((ll)m,b[i]))%=b[i];
        ans+=m*xx; m=m*b[i]/__gcd((ll)m,b[i]); (ans+=m)%=m;
    }
    printf("%lld",(ll)ans);
}
/*解同余方程
x%m=ans,x%b[i]=a[i]; 
则若x=x2*m+ans=x1*b[i]+a[i]
有m*x2-b[i]*x1=a[i]-ans
由EXGCD得m*x2-b[i]*x1=gcd(b[i],m)的解设为xx 
真正的解即为 x1=xx*(a[i]-ans)/gcd(b[i],m)
反代得ans=x1*m+ans,m=lcm(m,b[i])=m*b[i]/gcd(m,b[i])*/

猜你喜欢

转载自www.cnblogs.com/Ace-MYX/p/10364024.html