您的位置:首页 > 其它

中国余数定理

2013-01-25 23:16 232 查看
中国余数定理 先学扩展欧几里得吧>,<

看这篇
http://www.cnblogs.com/walker01/archive/2010/01/23/1654880.html
模数互质的情况FZU 1402

//模数互质的情况
#include<stdio.h>
#include<math.h>
#define ll __int64
ll div[15],rem[15];
ll n,d,x,y;
void ext_gcd(ll a,ll b) //求出a*x+b*y=gcd(a,b)=1时的X
{
    if(b==0)
    {
      x=1,y=0,d=a;
      return ;
    }
    else
    {
      ext_gcd(b,a%b);
      ll tmp=x;
          x=y;
          y=tmp-a/b*y;
    }
}
ll china_remainder(ll a[],ll b[])
{
    ll lcm=1;
    ll ans=0;
    int i;
    for(i=0;i<n;i++)
    lcm*=a[i];
    for(i=0;i<n;i++)
    {
        ll m=lcm/a[i];
        ext_gcd(m,a[i]);
        x=(x%a[i]+a[i])%a[i];//模数互质的情况下 此时求出的X就是a*x=1(mod b)
        ans=(ans+m*x*b[i]%lcm)%lcm;
    }
    return ans;
}
int main()
{
    freopen("in.txt","r",stdin);
    while(scanf("%d",&n)==1)
    {
        int i,j;
        for(i=0;i<n;i++)
        scanf("%I64d%I64d",&div[i],&rem[i]);
        printf("%I64d\n",china_remainder(div,rem));
    }
    return 0;
}


模数不互质的情况 HDU3579

这篇原理讲得比较清楚 http://972169909-qq-com.iteye.com/blog/1266328
//模数不互质的情况,合并同余方程
#include<stdio.h>
#include<math.h>
#define ll __int64
ll div[10],rem[10];
ll n,d,x,y;
ll gcd(ll a,ll b)
{ return b==0?a:gcd(b,a%b);}
void ext_gcd(ll a,ll b)
{
    if(b==0)
    {
      x=1,y=0,d=a;
      return ;
    }
    else
    {
      ext_gcd(b,a%b);
      ll tmp=x;
          x=y;
          y=tmp-a/b*y;
    }
}
ll china_remainder2(ll a[],ll b[])
{
    int flag=0;
    ll n1=a[0],b1=b[0],n2,b2,c;
    for(int i=1;i<n;i++)//依据上面所推公式进行合并
    {
        n2=a[i],b2=b[i];
        c=b2-b1;
        ext_gcd(n1,n2);
        if(c%d)
        {
            flag=1;
            break;
        }
        ll k=c/d*x;
        ll t=n2/d;
        if(t<0) t=-t;
        k=(k%t+t)%t;
        b1=b1+n1*k;
        n1=n1/d*n2;
    }
    if(flag)
    return -1;
    if(b1==0)//这题余数可能为0,需要特判,如果都为0,B1为所以除数的最小公倍数
    b1=n1;
    return b1;
}
int main()
{
    freopen("in.txt","r",stdin);
    int t;
    scanf("%d",&t);
    int ii;
    for(ii=1;ii<=t;ii++)
    {
        int i;
        scanf("%d",&n);
        for(i=0;i<n;i++)
        scanf("%I64d",&div[i]);
        for(i=0;i<n;i++)
        scanf("%I64d",&rem[i]);
        printf("Case %d: %I64d\n",ii,china_remainder2(div,rem));
    }
    return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: