【扩展中国剩余定理板子】POJ2891Strange Way to Express Integers

EXCRT的板题一道,就是给你几个同余方程求X 于是按照着来敲就好,普通crt要求两两互质,EXCRT不要求。 证明见:http://blog.csdn.net/clove_unique/article/details/54571216 zyf2000大佬。 最后公式:t=gcd(m1,m2),M=m1m2/t c=inv(m1/t,m2/t)((c2-c1)/t)%(m2/t)*m1+c1 答案 C%M 公式背牢就好 值得注意的是,EXCRT可能存在无解,无解情况:(c2-c1)%t!=0的时候无解。
值得注意的是,EXCRT可能存在无解,无解情况:(c2-c1)%t!=0的时候无解。

#include<iostream>
#include<cstdio>
#define maxn 1005
#define ll long long
using namespace std;
ll c[maxn],m[maxn],n,m1,c1,c2,m2,t;

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

ll gcd(ll a,ll b)
{
return b==0?a:gcd(b,a%b);
} 

ll inv(ll a,ll b)
{
ll xx,yy;
exgcd(a,b,xx,yy);
return (xx%b+b)%b;
}

int main()
{
while(~scanf("%lld",&n))
{
    for(int i=1;i<=n;i++)
    {
        scanf("%lld%lld",&m[i],&c[i]);
    }
    for(int i=2;i<=n;++i)
    {
        c1=c[i-1]; c2=c[i]; m1=m[i-1]; m2=m[i];
        t=gcd(m1,m2);
        if((c2-c1)%t){ printf("-1\n"); goto aha; }
        m[i]=(m1*m2)/t;
        c[i]=inv(m1/t,m2/t)*((c2-c1)/t)%(m2/t)*m1+c1;
        c[i]=(c[i]%m[i]+m[i])%m[i];
    }
    printf("%lld\n",c[n]);
    aha:;
}
}

     
posted @ 2018-03-20 23:36  Newuser233  阅读(7)  评论(0)    收藏  举报