扩展中国剩余定理 模板

#include <cstdio>
#define ll long long
const int N=1e5+10;
ll a[N],b[N],n;
void read(ll &x)
{
    char c=getchar();
    while(c<'0'||c>'9') c=getchar();
    while(c>='0'&&c<='9') {x=(x<<3)+(x<<1)+c-'0';c=getchar();}
}
ll exgcd(ll A,ll B,ll &x,ll &y)
{
    if(B==0)
    {
        y=0,x=1;
        return A;
    }
    ll gcd=exgcd(B,A%B,x,y);
    ll tmp=x;
    x=y;
    y=(tmp-A/B*y);
    return gcd;
}
ll slow_mul(ll x,ll y,ll mod)
{
    ll re=0;
    while(y)
    {
        if(y&1) re=re+x%mod;
        x=(x+x)%mod;
        y>>=1;
    }
    return re;
}
ll excrt()
{
    ll ans=a[1],M=b[1];
    for(int i=2;i<=n;i++)
    {
        ll A=M,B=b[i],d=((a[i]-ans)%B+B)%B,x,y;
        ll gcd=exgcd(A,B,x,y);
        x=slow_mul(x,d/gcd,B/gcd);
        M*=B/gcd;
        ans=(ans+x*A)%M;
    }
    return (ans%M+M)%M;
}
void init()
{
    read(n);
    for(int i=1;i<=n;i++) read(b[i]),read(a[i]);
}
int main()
{
    init();
    printf("%lld\n",excrt());
    return 0;
}

注意:
1.€€£不让用__int128,所以我们使用慢速乘
2.无解其实就是同余方程有无解

posted @ 2018-08-15 19:49  露迭月  阅读(321)  评论(0编辑  收藏  举报