zoukankan      html  css  js  c++  java
  • 中国剩余定理

    「物不知数」问题

    有物不知其数,三三数之剩二,五五数之剩三,七七数之剩二。问物几何?

    即求满足以下条件的整数:除以 (3)(2) ,除以 (5)(3) ,除以 (7)(2)

    该问题最早见于《孙子算经》中,并有该问题的具体解法。宋朝数学家秦九韶于 1247 年《数书九章》卷一、二《大衍类》对「物不知数」问题做出了完整系统的解答。上面具体问题的解答口诀由明朝数学家程大位在《算法统宗》中给出:

    三人同行七十希,五树梅花廿一支,七子团圆正半月,除百零五便得知。

    (2 imes 70+3 imes 21+2 imes 15=233=2 imes 105+23) ,故答案为 (23)

    算法简介及过程

    中国剩余定理 (Chinese Remainder Theorem, CRT) 可求解如下形式的一元线性同余方程组(其中 (n_1, n_2, cdots, n_k) 两两互质):

    [left { egin{array}{ccc} x &equiv& a_1 pmod {n_1} \ x &equiv& a_2 pmod {n_2} \ &vdots& \ x &equiv& a_k pmod {n_k} \ end{array} ight. ]

    上面的「物不知数」问题就是一元线性同余方程组的一个实例。

    算法流程

    1. 计算所有模数的积 (n)
    2. 对于第 (i) 个方程:
      1. 计算 (m_i=frac{n}{n_i})
      2. 计算 (m_i) 在模 (n_i) 意义下的 逆元 (m_i^{-1})
      3. 计算 (c_i=m_im_i^{-1})不要对 (n_i) 取模 )。
    3. 方程组的唯一解为: (a=sum_{i=1}^k a_ic_i pmod n)

    伪代码

    1 → n
    0 → ans
    for i = 1 to k
    	n * n[i] → n
    for i = 1 to k
    	n / n[i] → m
    	inv(m, n[i]) → b               // b * m mod n[i] = 1
    	(ans + a[i] * m * b) mod n → ans
    return ans
    

    算法的证明

    我们需要证明上面算法计算所得的 (a) 对于任意 (i=1,2,cdots,k) 满足 (aequiv a_i pmod {n_i})

    (i eq j) 时,有 (m_jequiv 0 pmod {n_i}) ,故 (c_jequiv m_jequiv 0 pmod {n_i}) 。又有 (c_iequiv m_i(m_i^{-1}mod {n_i})equiv 1 pmod {n_i}) ,所以我们有:

    [egin{aligned} a&equiv sum_{j=1}^k a_jc_j &pmod {n_i} \ &equiv a_ic_i &pmod {n_i} \ &equiv a_im_i(m^{-1}_i mod n_i) &pmod {n_i} \ &equiv a_i &pmod {n_i} end{aligned} ]

    即对于任意 (i=1,2,cdots,k) ,上面算法得到的 (a) 总是满足 (aequiv a_i pmod{n_i}) ,即证明了解同余方程组的算法的正确性。

    因为我们没有对输入的 (a_i) 作特殊限制,所以任何一组输入 ({a_i}) 都对应一个解 (a)

    另外,若 (x eq y) ,则总存在 (i) 使得 (x)(y) 在模 (n_i) 下不同余。

    故系数列表 ({a_i}) 与解 (a) 之间是一一映射关系,方程组总是有唯一解。

    下面演示 CRT 如何解「物不知数」问题。

    1. (n=3 imes 5 imes 7=105)
    2. 三人同行 七十 希: (n_1=3, m_1=n/n_1=35, m_1^{-1}equiv 2pmod 3) ,故 (c_1=35 imes 2=70)
    3. 五树梅花 廿一 支: (n_2=5, m_2=n/n_2=21, m_2^{-1}equiv 1pmod 5) ,故 (c_2=21 imes 1=21)
    4. 七子团圆正 半月(n_3=7, m_3=n/n_3=15, m_3^{-1}equiv 1pmod 7) ,故 (c_3=15 imes 1=15)
    5. 所以方程组的唯一解为 (aequiv 2 imes 70+3 imes 21+2 imes 15equiv 233equiv 23 pmod {105}) 。(除 百零五 便得知)

    应用

    某些计数问题或数论问题出于加长代码、增加难度、或者是一些其他不可告人的原因,给出的模数: 不是质数

    但是对其质因数分解会发现它没有平方因子,也就是该模数是由一些不重复的质数相乘得到。

    那么我们可以分别对这些模数进行计算,最后用 CRT 合并答案。

    推荐练习:BZOJ 1951

    比较两 CRT 下整数

    考虑 CRT, 不妨假设 (n_1leq n_2 leq ... leq n_k)

    [left{ egin{array} { r l } { x } & { equiv a _ { 1 } left( mod n _ { 1 } ight) } \ { x } & { equiv a _ { 2 } left( mod n _ { 2 } ight) } \ { } & { vdots } \ { x } & { equiv a _ { k } left( mod n _ { k } ight) } end{array} ight. ]

    与 PMR(Primorial Mixed Radix) 表示

    (x=b_1+b_2n_1+b_3n_1n_2...+b_kn_1n_2...n_{k-1} ,b_iin [0,n_i))

    将数字转化到 PMR 下,逐位比较即可

    转化方法考虑依次对 PMR 取模

    [egin{aligned} b_1&=a_1 mod n_1\ b_2&=(a_2-b_1)c_{1,2} mod n_2\ b_3&=((a_3-b_1')c_{1,3}-x_2')c_{2,3} mod n_3\ &...\ b_k&=(...((a_k-b_1)c_{1,k}-b_2)c_{2,k})-...)c_{k-1,k} mod n_k end{aligned} ]

    其中 (c_{i,j}) 表示 (n_i)(n_j) 的逆元, (c_{i,j}n_i equiv 1 pmod {n_j})

    扩展:模数不互质的情况

    两个方程

    设两个方程分别是 (xequiv a_1 pmod {m_1})(xequiv a_2 pmod {m_2})

    将它们转化为不定方程: (x=m_1p+a_1=m_2q+a_2) ,其中 (p, q) 是整数,则有 (m_1p-m_2q=a_2-a_1)

    由裴蜀定理,当 (a_2-a_1) 不能被 (gcd(m_1,m_2)) 整除时,无解;

    其他情况下,可以通过扩展欧几里得算法解出来一组可行解 ((p, q))

    则原来的两方程组成的模方程组的解为 (xequiv bpmod M) ,其中 (b=m_1p+a_1)(M= ext{lcm}(m_1, m_2))

    多个方程

    用上面的方法两两合并就可以了……

    推荐练习:POJ 2891

    【模板】扩展中国剩余定理

    「NOI2018」屠龙勇士

    「TJOI2009」猜数字

    「SDOI2010」古代猪文

    李永乐老师视频讲解

  • 相关阅读:
    React 学习笔记
    需要充实自己的课外东西
    近期计划
    测试TinyMCE编辑器
    我的第二篇博客园随笔
    博客已搬运至https://wz71014q.github.io
    关于HTTPS通信机制的笔记
    JS中数组的一些笔记
    Three学习之曲线
    Three入门学习笔记整理
  • 原文地址:https://www.cnblogs.com/RioTian/p/13469707.html
Copyright © 2011-2022 走看看