孙子问题-中国剩余定理

孙子问题

“孙子问题”在现代数论中是一个一次同余问题,它最早出现在我国公元四世纪的数学著作《孙子算经》中。《孙子算经》卷下“物不知数”题说:有物不知其数,三个一数余二,五个一数余三,七个一数又余二,问该物总数几何?显然,这相当于求不定方程组:
N=3x+2 ,
N=5y+3 ,
N=7z+2 ,
《孙子算经》所给答案是N=23。由于孙子问题数据比较简单,这个答数通过试算也可以得到。中国数学家秦九韶于1247年做出了完整的解答,口诀如下:
三人同行七十希,
五树梅花廿一支,
七子团圆正半月,
除百零五使得知。
这个解法实际上是,首先利用秦九韶发明的大衍求一术求出5和7的最小公倍数35的倍数中除以3余数为1的最小一个70(这个称为35相对于3的数论倒数),3和7的最小公倍数21相对于5的数论倒数21,3和5的最小公倍数15相对于7的数论倒数15。然后70×2+21×3+15×2-2×105=233便是可能的解之一。它加减3、5、7的最小公倍数105的若干倍仍然是解,因此最小的解为233除以105的余数23。

附注:这个解法并非最简,因为实际上35就符合除3余2的特性,所以最小解是:35×1+21×3+15×2-105=23。最小解加上105的正整数倍都是解。

分析

下面分析一下孙子算经的算法,一个数满足除以3余2,除以5余3,除以7余2.那么我们先假设这个数N = A+B+C。如果A除以3余2(A≡2(mod3))且B和C是3的倍数。B除以5余3(B≡3(mod5))且A,C都是5的倍数,C除以7余2(C≡2(mod7))且A,B都是7的倍数。那么N就是我们要找的数。总结下来,A应该满A≡2(mod3)且A是5和7的公倍数;B≡3(mod5),且B是3和7的公倍数;C≡2(mod7),且C是3和5的公倍数。我们设A=k1*35(35是5和7的最小公倍数,则k1*35可以表示5和7的所有公倍数,k1是正整数)B=k2*21,C=k3*15;再取合适的k1,k2,k3的值使得A≡2(mod3),B≡3(mod5),C≡2(mod7).可得A=140,B=63,C=30.则N=233,又因为3,5,7的最小公倍数是105,在减去105得23.故所得最小整数为23,N=23+K*105都满足条件。
我们可以将上诉问题改为求一次同余方程的形式即:
K1*35≡1(mod3)求出K1*35的最小值为70,k1=2;
K2*21≡1(mod5)求出K2*21的最小值为21,k2=1;
K3*15≡1(mod7)求出K3*15的最小值为15,k3=1;
我们想得到A模3余1题中要求余2,所以用70再乘以2就得到A,这时A模3就余2了,同理用21*3,15乘以2。再相加得到N=2*35*2+1*21*3+1*15*2=233。233所在的模105的剩余类都满足条件即N=23+K*105.

乘法逆元

例如:4关于模7的乘法逆元为多少?
4*X≡1(mod 7)
这个方程等价于求一个X和K,满足
4X=7K+1
其中X和K都是整数。
若ax=1 mod f 则称a关于模f的乘法逆元为x。也可表示为ax≡1(mod f)。
当a与f互素时,a关于模f的乘法逆元有唯一解。如果不互素,则无解。如果f为素数,则从1到f-1的任意数都与f互素,即在1到f-1之间都恰好有一个关于模f的乘法逆元。
例如,求5关于模14的乘法逆元:
14=5*2+4
5=4+1
说明5与14互素,存在5关于14的乘法逆元。
1=5-4=5-(14-5*2)=5*3-14
因此,5关于模14的乘法逆元为3。
在模运算中,
加法单位元是0,因为(0+a) mod m = a mod m;
乘法单位元是1,因为(1×a) mod m = a mod m
定义 对a∈Zm,存在b∈Zm,使得a+b ≡ 0 (mod m),则b是a的加法逆元,记b= - a。
定义 对a∈Zm,存在b∈Zm,使得a×b ≡1 (mod m),则称b为a的乘法逆元。

求乘法逆元

其求法可用欧几里德算法:
Extended Euclid(d,f)//算法求d关于模f的乘法逆元 d1 ,即 dd1modf=1

  1. (X1,X2,X3) := (1,0,f); (Y1,Y2,Y3) := (0,1,d)
  2. if (Y3=0) then return d1 = null //无逆元
  3. if (Y3=1) then return d1 = Y2 //Y2为逆元
  4. Q := X3 div Y3 //整除
  5. (T1,T2,T3) := (X1 - Q*Y1 , X2 - Q*Y2,X3 - Q*Y3)
  6. (X1,X2,X3) := (Y1,Y2,Y3)
  7. (Y1,Y2,Y3) := (T1,T2,T3)
  8. goto 2

中国剩余定理

以上解法若推广到一般情况,便得到了中国剩余定理的一个构造性证明。
一般地,中国剩余定理是指若有一些两两互质的整数 ,则对任意的整数:a1,a2,…an,以下联立同余方程组对模有公解:
这里写图片描述
有解的判定条件,并用构造法给出了在有解情况下解的具体形式。
中国剩余定理说明:假设整数 m1,m2,...,mn 两两互质,则对任意的整数: a1,a2,...,an ,以上同余方程组 有解,并且通解可以用如下方式构造得到:
M=m1m2...mn=ni=1mi 是整数 m1,m2,...,mn 的乘积,并设 Mi=M/mi 是除了 mi 以外的 n1 个整数的乘积。
ti=M1i Mi mi 的数论倒数( ti Mi mi 意义下的乘法逆元) Miti1(modm)i{1,2,3,...,n}
以上同余方程组的通解形式为

x=a1t1M1+a2t2M2+...+antnMn+kM=i=1naitiMi+kM,kZ.

在模 M 的意义下,方程组只有一个解:
x=i=1naitiMi(modM)

同余方程代码

扩展欧几里得算法的推导参考:扩展欧几里得算法

#include <stdio.h>

typedef long long ll;

ll Extended_Euclid(ll a, ll b, ll *x, ll *y)
{
    int d;
    if (b==0)
    {
        *x=1;
        *y=0;
        return a;
    }
    printf("before a:%lld,b:%lld,*x:%lld,*y:%lld\r\n",a,b,*x,*y);
    d = Extended_Euclid(b, a%b, x, y);
    ll temp = *x;
    *x = *y;
    *y = temp - a/b*(*y);
    printf("after a:%lld,b:%lld,*x:%lld,*y:%lld\r\n",a,b,*x,*y);
    return d;
}

ll Chinese_Remainder(ll a[], ll w[], ll len)
{
    ll i, d, x=0, y=0, m, n, ret;
    ret=0;
    n=1;
    for (i=0;i<len;i++)
    {
        n*=w[i];
    }
    for (i=0;i<len;i++)
    {
        m=n/w[i];
        d = Extended_Euclid(w[i], m, &x, &y);
        printf("x:%lld,y:%lld\r\n",x,y);
        ret=(ret+y*m*a[i])%n;
    }
    return (n+ret%n)%n;
}

int main()
{
    ll a[] = {2,3,2},w[] = {3,5,7};
    printf("Chinese_Remainder:%lld\r\n",Chinese_Remainder(a,w,3));
    return 0;
}
  • 0
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值