POJ 2891 Strange Way to Express Integers(中国剩余定理)

题意:

  

题目给定多个式子,x\equivai(mod mi), 因为不确定其中 ai,mi 的关系,也就是说不清楚是否互质,所以,例如有两个式子

x=r1+k1*a1   -----(1)

x=r2+k2*a2   -----(2)

求 x ,根据扩展欧几里得原理,两式相等得:k1*a1-k2*a2=r2-r1,其中要满足 r2-r1=k*gcd(a1,a2)

所以利用函数 ex_gcd 求解 x 的答案,进而求得 k1 的值,这样 (1) 式就有了答案,因为 (1)式中的 x 的值同样要满足(2) 式,所以 x=x‘( (1)式中 x 的值 )+k*lcm(a1,a2)

变为 x\equivx'(mod lcm(a1,a2))

inline void write(ll x)
{
    if(x<0){ putchar('-');x=-x; }
    if(x>9)write(x/10);
    putchar(x%10+'0');
}

const int N=1e5+5;
const ll mod=21252;
 
    int n,m,t;
    int i,j,k;
    ll a[N],r[N];

ll ex_gcd(ll a,ll b,ll &x,ll &y) //ax+by=gcd(a,b)
{
    ll gcd=a;
    if(!b) x=1,y=0;
    else {
        gcd=ex_gcd(b,a%b,y,x);
        y-=(a/b)*x;
    }
    return gcd;
}

void rep(ll &x,ll mod)
{
    x%=mod;
    x+=mod;
    x%=mod;
    if(!x) x=mod;
}

ll China()
{
    ll A=a[1],x,y,ans=r[1];
    for(int i=2;i<=n;i++){
        ll d=ex_gcd(A,a[i],x,y); // Ax+a[i]y=gcd(A,a[i])
        if((r[i]-ans)%d) return -1;

        x=x*(r[i]-ans)/d; //将求解的 x 扩大 k 倍
        rep(x,a[i]/d);
        ans=x*A+ans;
        A=A/d*a[i];
        rep(ans,A);
    }
    return ans;
}

int main()
{
    //IOS;
    while(~sd(n)){
        for(i=1;i<=n;i++) sll(a[i]),sll(r[i]);
        write(China());
        puts("");
    }
    //PAUSE;
    return 0;
}

 

已标记关键词 清除标记
©️2020 CSDN 皮肤主题: 酷酷鲨 设计师:CSDN官方博客 返回首页