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

https://www.luogu.org/problem/P4777

#include <iostream>
#include <cstdio>
#include <queue>
#include <algorithm>
#include <cmath>
#include <cstring>
#define inf 2147483647
#define N 1000010
#define p(a) putchar(a)
#define For(i,a,b) for(long long i=a;i<=b;++i)
//by war
//2019.8.8
using namespace std;
long long T,n;
long long r[N],a[N],x,y,gcd,flag;
void in(long long &x){
    long long y=1;char c=getchar();x=0;
    while(c<'0'||c>'9'){if(c=='-')y=-1;c=getchar();}
    while(c<='9'&&c>='0'){ x=(x<<1)+(x<<3)+c-'0';c=getchar();}
    x*=y;
}
void o(long long x){
    if(x<0){p('-');x=-x;}
    if(x>9)o(x/10);
    p(x%10+'0');
}

long long msc(long long a,long long b){
    long long r=0,y=1;
    if((a^b)<0)  y*=-1;
    a=abs(a);b=abs(b);
    while(b>0){
        if(b&1)
            r+=a;
        a<<=1;
        b>>=1;
    }
    return r*y;
}

long long mscc(long long a,long long b,long long p){
    long long r=0,y=1;
    if((a^b)<0)  y*=-1;
    a=abs(a);b=abs(b);
    while(b>0){
        if(b&1)
            r=(r+a)%p;
        a=(a<<1)%p;
        b>>=1;
    }
    return r*y;
}

void exgcd(long long a,long long b,long long &x,long long &y){
    if(!b){
        x=1;y=0;gcd=a;
        return;
    }
    exgcd(b,a%b,y,x);
    y-=msc(a/b,x);
}

signed main(){
    in(n);    
    For(i,1,n)
        in(r[i]),in(a[i]);
    For(i,2,n){
        exgcd(r[1],r[i],x,y);
        y=r[i]/gcd;
        x=mscc(x,(a[i]-a[1])/gcd,y);        
        x=(x+y)%y;
        a[1]+=msc(r[1],x);
        r[1]=msc(r[1]/gcd,r[i]);
    }
    o(a[1]%r[1]);
    return 0;
}

 

posted @ 2019-08-08 21:05  WeiAR  阅读(162)  评论(0编辑  收藏  举报