Strange Way to Express Integers-----不互质的中国剩余定理

参考文章地址:http://blog.csdn.net/hqd_acm/article/details/6173859

题目:http://poj.org/problem?id=2891

思路:

x=r1 (mod a1)  
x=r2 (mod a2)
--->a1*x+a2*y=gcd(a1,a2)=d
--->r1+a1*x=r2+a2*y  ---> a1*x+a2*y=r2-r1   (1)
则(r2-r1)%d!=0,方程(1)的解不存在。
否则
{
    t=a2/d;
    x=((x*(r2-r1)/d)%t+t)%t//x的最小整数解
    r1=x*a1+r1   //求出原方程X=a1*x+r1
    a1=a1*a2/d;  
    r1=(r1%a1+a1)%a1;  //r1<a1
}
思想就是要将两个方程式合并,合并式X=a3x+r3,既要mod a1=r1,而且要mod  a2=r2,所以有a3是a1与a2的最小公倍数,r3是方程a1*x+a2*y=r2-r1的解。

源代码:

#include <stdio.h>

typedef long long ll;

ll n,a[100000],r[100000];

ll extend_gcd(ll a,ll b,ll &x,ll &y)
{
    ll t,ans;
    if(b==0)  {  x=1; y=0; return a ;}
    else
    {
        ans=extend_gcd(b,a%b,x,y);
        t=x;   x=y;    y=t-a/b*y;
    }
    return ans;
}

void solve(ll a[],ll r[],ll n)
{
    ll a1,a2,r1,r2,x,y,d,t;
    int flag;
    a1=a[0];  r1=r[0];
    if(n==1)
    {
        if(a1<=r1)  printf("-1\n");
    //    else
        printf("%lld\n",r1);
        return;
    }
    flag=1;
    for(int i=1;i<n;i++)
    {
        a2=a[i];  r2=r[i];
       if(a2<=r2) {  printf("-1\n"); flag=0;  break; }
        d=extend_gcd(a1,a2,x,y);
        if((r2-r1)%d!=0)  {  printf("-1\n"); flag=0;  break; }
        else
        {
            t=a2/d;
            x=(x*(r2-r1)/d%t+t)%t;
            r1=a1*x+r1;
            a1=a1*a2/d;
            r1=(r1%a1+a1)%a1;
        }
    }
    if(flag)  printf("%lld\n",r1);
}

int main()
{
    while(scanf("%lld",&n)!=EOF)
    {
        for(int i=0;i<n;i++)
        scanf("%lld %lld",&a[i],&r[i]);
        solve(a,r,n);
    }
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值