中国剩余定理(孙子定理)

中国剩余定理

\quad 在《孙子算经》中有这样一个问题:“今有物不知其数,三三数之剩二(除以 3 3 3 2 2 2),五五数之剩三(除以 5 5 5 3 3 3),七七数之 剩二(除以 7 7 7 2 2 2),问物几何?”这个问题称为“孙子问题”,该问题的一般解法国际上称为“中国剩余定理”。

具体解法分三步:

  1. 找出三个数:从 3 3 3 5 5 5的公倍数中找出被 7 7 7除余 1 1 1的最小数 15 15 15,从 3 3 3 7 7 7的公倍数中找出被 5 5 5除余 1 1 1的最小数 21 21 21,最后从 5 5 5 7 7 7的公倍数中找出除 3 3 3 1 1 1的最小数 70 70 70
  2. 15 15 15乘以 2 2 2 2 2 2为最终结果除以 7 7 7的余数),用 21 21 21乘以 3 3 3 3 3 3为最终结果除以 5 5 5的余数),同理,用 70 70 70乘以 2 2 2 2 2 2为最终结果除以 3 3 3的余数),然后把三个乘积相加 15 ∗ 2 + 21 ∗ 3 + 70 ∗ 2 15∗2+21∗3+70∗2 152+213+702得到和 233 233 233
  3. 233 233 233除以 3 , 5 , 7 3,5,7 357三个数的最小公倍数 105 105 105,得到余数 23 23 23,即 233 233%105=23 233。这个余数 23 23 23就是符合条件的最小数。

\quad 就这么简单。我们在感叹神奇的同时不禁想知道古人是如何想到这个方法的,有什么基本的数学依据吗?

\quad 我们将“孙子问题”拆分成几个简单的小问题,从零开始,试图揣测古人是如何推导出这个解法的。

\quad 首先,我们假设 n 1 n_{1} n1是满足除以 3 3 3 2 2 2的一个数,比如 2 , 5 , 8 2,5,8 258等等,也就是满足 3 ∗ k + 2 ( k > = 0 ) 3∗k+2(k>=0) 3k+2k>=0)的一个任意数。同样,我们假设 n 2 n_{2} n2是满足除以 5 5 5 3 3 3的一个数, n 3 n_{3} n3是满足除以 7 7 7 2 2 2的一个数。

\quad 有了前面的假设,我们先从 n 1 n_{1} n1这个角度出发,已知 n 1 n_{1} n1满足除以 3 3 3 2 2 2,能不能使得 n 1 + n 2 n_{1}+n_{2} n1+n2的和仍然满足除以 3 3 3 2 2 2?进而使得 n 1 + n 2 + n 3 n_{1}+n_{2}+n_{3} n1+n2+n3的和仍然满足除以 3 3 3 2 2 2

\quad 这就牵涉到一个最基本数学定理,如果有 a % b = c a\%b=c a%b=c,则有 ( a + k ∗ b ) % b = c (a+k∗b)\%b=c (a+kb)%b=c( k k k为非零整数),换句话说,如果一个除法运算的余数为 c c c,那么被除数与 k k k倍的除数相加(或相减)的和(差)再与除数相除,余数不变。这个是很好证明的。

\quad 以此定理为依据,如果 n 2 n_{2} n2 3 3 3的倍数, n 1 + n 2 n_{1}+n_{2} n1+n2就依然满足除以 3 3 3 2 2 2。同理,如果 n 3 n_{3} n3也是 3 3 3的倍数,那么 n 1 + n 2 + n 3 n_{1}+n_{2}+n_{3} n1+n2+n3的和就满足除以 3 3 3 2 2 2。这是从 n 1 n_{1} n1的角度考虑的,再从 n 2 , n 3 n_{2},n_{3} n2,n3的角度出发,我们可推导出以下三点:

  • 为使 n 1 + n 2 + n 3 n_{1}+n_{2}+n_{3} n1+n2+n3的和满足除以 3 3 3 2 2 2 n 2 n_{2} n2 n 3 n_{3} n3必须是 3 3 3的倍数。
  • 为使 n 1 + n 2 + n 3 n_{1}+n_{2}+n_{3} n1+n2+n3的和满足除以 5 5 5 3 3 3 n 1 n_{1} n1 n 3 n_{3} n3必须是 5 5 5的倍数。
  • 为使 n 1 + n 2 + n 3 n_{1}+n_{2}+n_{3} n1+n2+n3的和满足除以 7 7 7 2 2 2 n 1 n_{1} n1 n 2 n_{2} n2必须是 7 7 7的倍数。

\quad 因此,为使 n 1 + n 2 + n 3 n_{1}+n_{2}+n_{3} n1+n2+n3的和作为“孙子问题”的一个最终解,需满足:

  1. n 1 n_{1} n1除以 3 3 3 2 2 2,且是 5 5 5 7 7 7的公倍数。
  2. n 2 n_{2} n2除以 5 5 5 3 3 3,且是 3 3 3 5 5 5的公倍数。
  3. n 3 n_{3} n3除以 7 7 7 2 2 2,且是 3 3 3 5 5 5的公倍数。

\quad 所以,孙子问题解法的本质是从 5 5 5 7 7 7的公倍数中找一个除以 3 3 3 2 2 2的数 n 1 n_{1} n1,从 3 3 3 7 7 7的公倍数中找一个除以 5 5 5 3 3 3的数 n 2 n_{2} n2,从 3 3 3 5 5 5的公倍数中找一个除以 7 7 7 2 2 2的数 n 3 n_{3} n3,再将三个数相加得到解。在求 n 1 , n 2 , n 3 n_{1},n_{2},n_{3} n1,n2,n3时又用了一个小技巧,以 n 1 n_{1} n1为例,并非从 5 5 5 7 7 7的公倍数中直接找一个除以 3 3 3 2 2 2的数,而是先找一个除以 3 3 3 1 1 1的数,再乘以 2 2 2也就是先求出 5 5 5 7 7 7的公倍数模 3 3 3下的逆元,再用逆元去乘余数。

\quad 最后,我们还要清楚一点, n 1 + n 2 + n 3 n_{1}+n_{2}+n_{3} n1+n2+n3只是问题的一个解,并不是最小的解。如何得到最小解?我们只需要从中最大限度的减掉掉 3 , 5 , 7 3,5,7 357的公倍数 105 105 105即可。道理就是前面讲过的定理“如果 a % b = c a\%b=c a%b=c,则有 ( a − k ∗ b ) % b = c ” (a−k∗b)\%b=c” (akb)%b=c。所以 ( n 1 + n 2 + n 3 ) % 105 (n_{1}+n_{2}+n_{3})\%105 n1+n2+n3%105就是最终的最小解。

这样就得到了中国剩余定理的公式:

设正整数 m 1 , m 2 , , , , , m k m_{1},m_{2},,,,,m_{k} m1,m2,,,,,mk两两互素,则同余方程组
在这里插入图片描述
那么再看提到的一元线性同余方程:(先做几个设定:设 N i N_{i} Ni为能够被 m 1 , m 2 , . . . . . . , m i − 1 , m i + 1 , . . . . . m k m_{1}, m_{2},......, m_{i-1}, m_{i+1}, .....m_{k} m1,m2,......,mi1,mi+1,.....mk整除,但是除以 m i m_{i} mi正好余1)

X = N 1 ∗ a 1 + N 2 ∗ a 2 + . . . . . . . + N n ∗ a n X = N_{1}*a_{1} + N_{2}*a_{2} + ....... + N_{n}*a_{n} X=N1a1+N2a2+.......+Nnan

就是我们要求的一个解,解集为 X % L C M ( m 1 , m 2 , . . . . , m n ) X \% LCM(m_{1}, m_{2}, ...., m_{n}) X%LCM(m1,m2,....,mn)

剩下的问题就变成了如何求解$ N_{1}, N_{2} … N_{n}$,我们继续向下看:

假设 m = L C M ( m 1 , m 2 , . . . . , m n ) m = LCM(m_{1}, m_{2}, ...., m_{n}) m=LCM(m1,m2,....,mn) x ′ , y ′ x', y' x,y为任意整数。

因为 N i N_{i} Ni的性质, N i N_{i} Ni可以表示为: N i = = m / m i ∗ x ′ = = m i ∗ y ′ + 1 = = > m / m i ∗ x ′ + ( − m i ) ∗ y ′ = = 1. N_{i} == m / m_{i} * x' == m_{i} * y' + 1 ==> m / m_{i}* x' + (-m_{i}) * y' == 1. Ni==m/mix==miy+1==>m/mix+(mi)y==1.

推到现在有没有感觉很熟悉,对的!这个就是扩展欧几里德:

对于 g c d ( a , b ) = d gcd(a, b) = d gcd(a,b)=d, 存在 a ∗ x + b ∗ y = = g c d ( a , b ) a*x+b*y == gcd(a, b) ax+by==gcd(a,b);

存在 g c d ( − m i , m / m i ) = = 1 gcd(-m_{i}, m/m_{i}) == 1 gcd(mi,m/mi)==1,

对于 m / m i ∗ x ′ + ( − m i ) ∗ y ′ = = 1 , m/m_{i} * x' + (-m_{i}) * y' == 1, m/mix+(mi)y==1,

套用一下扩展欧几里德求出 x ′ , x', x, 就可以求解出 N i N_{i} Ni。有了 N i N_{i} Ni求出 X X X就是分分钟的事情!

Code:

//中国剩余定理模板
ll china(int a[],int b[],int n)//a[]为除数,b[]为余数
{
    int M=1,y,x=0;
    for(int i=0; i<n; ++i) //算出它们累乘的结果
        M*=a[i];
    for(int i=0; i<n; ++i)
    {
        int w=M/a[i];
        int tx=0;
        int t=exgcd(w,a[i],tx,y);//计算逆元
        x=(x+w*(b[i]/t)*x)%M;
    }
    return (x+M)%M;
}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值