中国剩余定理

中国剩余定理

http://hi.baidu.com/nicker2010/item/91a91fd14133073b2a35c7ed

问题:今有物不知其数,三三数之有二,五五数之有三,七七数之有二,问物有多少?

数学表达式如下,求x。

x mod 3=2

x mod 5=3

x mod 7=2

 定理1: 

设m1,m2,…mk是两两互素的正整数,则对任意b1,b2,…,bk,同余方程组

x mod m1 = b1 mod m1,

x mod m2 = b2 mod m2, 

x mod mk=bkmod mk, 

其解为: x=(M1’M1b1+M2’M2b2+…+M’kMkbk )mod m

其中:m=m1m2…mk, Mi=m/mi, MiMi’ mod mi=1 显然(Mi,mi)=1即Mi’是Mi的逆元

 

上面的例子解如下:

m1=3   m2=5   m3=7   b1=2   b2=3   b3=2

m=m1*m2*m3=3*5*7=105

M1=m/m1=5*7=35  M1’=2

M2=21,  M2'=1

M3=15,  M3'=1

则解X为

X=(M1’*M1*b1+M2’*M2*b2+M3’*M3*b3)%m= (140+63+30)%105 = 23

 

逆元的求法(C#代码,必须保证num和modeNum互质才有解):

publicstaticintGetOpposite(intnum,intmodeNum)
{
    intopposite =0;
    intremainder =0;
    inttemp1 =0;
    inttemp2 =1;

    //将较小的数作为 modeNum
    if(modeNum > num)
     {
         num = num + modeNum;
         modeNum = num - modeNum;
         num = num - modeNum;
     }
    //将num 保存起来,如果最终的余数小于零,将其转换成大于零的数
    inttempNum = num;
    do
     {
         remainder = num % modeNum;
        if(remainder!=0)
         {
             opposite = -1* num / modeNum * temp2 + temp1;
         }
         temp1 = temp2;
         temp2 = opposite;
         num = modeNum;
         modeNum = remainder;
     }
    while(remainder!=0);           
    returnopposite>0?opposite:opposite+tempNum;
}

 

代码二,求逆元:

//扩展欧几里得
long long exgcd(long long a,long long b,long long &x,long long &y)
{
 if(a==0){
 x=0;
 y=1;
 return b;
 }
 long long g=exgcd(b%a,a,x,y);
 long long tem=y;
 y=x;
 x=tem-(b/a)*y;
 return g;
}
long long inv(long long a,long long n)//求逆元
{
 long long x,y;
 exgcd(a,n,x,y);
 return (x%n+n)%n;
}
long long apmodm(long long a,long long b,long long  m){//a^p mod m
 
 if(b==0)return 1%m;
 if(b==1)return a%m;
       long long tem= apmodm(a,b>>1,m);
 if(!(b&1))return  tem*tem%m;
 else return(((tem*tem)%m)*(a%m))%m;
}   
//一个公式:求 p^0+p^1+p^2....p^n mod m 的余数
long long solve(long long p,long long n,long long m)
{
 if((p-1)%m==0) return (apmodm(p,n+1,m*(p-1))-1)/(p-1);//公式 a/b mod m==a mod(m*b)/b 当 b|a的时候
 return ((apmodm(p,n+1,m)-1)*inv(p-1,m))%m;
}
//分治的方法
long long solve(long long p,long long n,long long m)
{
 if(n==0)return 1%m;
 long long tem=solve(p,n>>1,m);
 if(n&1)return tem*(apmodm(p,(n>>1)+1,m)+1)%m;
 return (solve(p,n-1,m)+apmodm(p,n,m))%m;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值