zoukankan      html  css  js  c++  java
  • 一文搞懂裴蜀、扩欧、乘法逆元、中国剩余定理

    参考:
    OI Wiki
    《算法导论》第31章 数论算法
    扩展欧几里德 为什么必定存在ax+by==gcd(a,b)_百度知道
    如何通俗易懂、严谨且详细地讲解扩展欧几里得算法? - 桑山阴阴阴阴阴阴的回答 - 知乎
    【洛谷日报#205】乘法逆元
    中国剩余定理谁能用平易近人的语言推导一下•••? - 知乎
    5÷2=6?——是的,模7意义下 - Bat特白的文章 - 知乎

    前置知识

    要看懂本文,你需要认得这些符号:(amid b)(a) 整除 (b)(b) 能被 (a) 整除),(amod b)(a equiv b pmod m)(gcd(a,b))(operatorname{lcm}(a,b))(lfloor x floor)

    如果不认识这些符号,看 OI Wiki

    裴蜀定理

    裴蜀定理,又称贝祖定理(Bézout's lemma),是一个关于最大公约数的定理。

    其内容是:

    (a,b) 是不全为零的整数,则存在整数 (x,y),使得 (ax+by=gcd(a,b)).

    证明

    (a,b) 线性组合集为 (S={zmid z=ax+by,xinmathbb{Z},yinmathbb{Z}}),那么裴蜀定理说的就是 (gcd(a,b)in S)。实际上,我们可以证明 (gcd(a,b))(S) 中的最小正元素。

    为了证明这个,我们先来看看集合 (S) 有什么性质。

    1. (z_1in S, z_2in S),那么 (z_1pm z_2 in S)

      推导:对于 (S) 中的任意两个元素 (z_1,z_2),由定义知它们可以写成这样的形式:(z_1=ax_1+by_1,z_2=ax_2+by_2) ((x_1,y_1,x_1,y_2inmathbb{Z})),那么 (z_1+z_2=a(x_1+x_2)+b(y_1+y_2)) 也属于集合 (S)

    2. (zin S),则 (kzin S) ((kin mathbb{Z}))

      推导:因为 (zin S),所以 (z) 可以写成 (ax+by) ((x,yinmathbb{Z})),那么 (z) 的整数倍 (kz) ((kinmathbb{Z})) 可以写成 (a(kx)+b(ky)),因为 (kx,ky) 是整数,所以 (kz) 也在集合 (S) 中。

    3. (z_1in S, z_2in S),那么 (z_1mod z_2 in S)

      推导:(z_1mod z_2) 一定可以写成 (z_1 - kz_2) ((kinmathbb{Z})) 的形式,(z_2in S) 可推出 (-kz_2in S),又因为 (z_1in S),所以 (z_1-kz_2in S),即 (z_1mod z_2 in S)

    4. (S) 中的所有元素都能被 (gcd(a,b)) 整除。

      推导:需要注意的是 (0) 可以被任何整数整除,而且 (dmid a) 等价于 (-dmid a)
      (gcd(a,b))(a,b) 的最大公约数,那么 (a,b)(gcd(a,b)) 的整数倍,即 (a=k_1gcd(a,b),b=k_2gcd(a,b)) ((k_1,k_2inmathbb{Z})),所以 (ax+by=(k_1x+k_2y)gcd(a,b)) 也是 (gcd(a,b)) 的整数倍,即能被 (gcd(a,b)) 整除。

    (d)(S) 中最小的正数,即 (ax+by) ((x,yinmathbb{Z})) 取值中的最小正整数。首先,由性质 4 可知,(d) 能被 (gcd(a,b)) 整除,所以 (dge gcd(a,b))

    再设 (e)(S) 中任意一个整数。由性质 3 可知,(e mod d in S)。又因为 (emod d) 的结果是 ([0,d-1]) 范围内的整数,而 (S) 中最小的正数是 (d),因此 (emod d) 只能取 (0),即 (e) 能被 (d) 整除。也就是说,(S) 中任意一个整数都能被 (d) 整除。

    因为 (ain S),所以 (a) 能被 (d) 整除;同理 (b) 也能被 (d) 整除。所以 (d)(a,b) 的公约数,所以 (dle gcd(a,b))

    而前面证过 (dge gcd(a,b)),所以 (d) 只能取 (gcd(a,b))

    扩展欧几里得算法

    前面我们已经证明了方程 (ax + by = gcd(a,b)) 一定有整数解,但是我们不知道此时 (x,y) 取什么值。扩展欧几里得就是用来解出 (x,y) 的值的算法。

    定义函数 (operatorname{exgcd}(a,b)),它返回 (ax + by = gcd(a,b)) 的整数解 ((x,y))

    如果 (b e 0),则有 (gcd(a,b) = gcd(b,amod b))

    假设我们已经求出 (operatorname{exgcd}(b,a mod b)) 的解 ((x',y')),那么 (ax+by = bx'+(amod b)y'),即

    [ax+by=bx'+(a - b imesleftlfloor a/b ight floor )y' ]

    整理得

    [ax+by=ay'+b(x'-[a/b]y') ]

    所以 (x=y') (y=x'-[a/b]y')

    问题就成了如何求 (operatorname{exgcd}(b,amod b))

    递归下去。当 (b=0) 的时候可以直接出解。

    乘法逆元

    在 OI 中,大多数情况下,善良的出题人为了避免高精度等大整数计算,常常会要求输出答案对一个数(大多是质数)取模的情况,但这衍生了一个问题:若题目中计算需用到除法,而 (a equiv b pmod{c}) 不能推出 (leftlfloor frac {a} {d} ight floor equiv leftlfloor frac {b} {d} ight floor pmod{c}),要解决这个问题,就需要用到一个概念:乘法逆元。

    定义

    如果您到百度上搜索逆元,您会看到如下定义:(这里逆元素是逆元的全称)

    逆元素是指一个可以取消另一给定元素运算的元素

    我们来举个例子吧,先在实数范围举例,由小学知识可知,如果一个代数式 (F) 乘一个数 (a) 后,再乘它的倒数 (frac {1} {a})​,相当于没有乘 (a)(这里不考虑 (0) 的情况),换句话说,我们乘 (frac {1} {a})​ 后,取消了代数式 (F)(a) 后值增大的影响。

    不难发现这符合逆元的定义,故我们可以说一个数和其倒数互为乘法逆元。除此之外,我们还能发现一个数和其相反数互为加法逆元等等……

    上文在实数范围内讨论了乘法逆元,现在我们来看本文主要讨论的内容,数论模意义下的乘法逆元。

    由上文的分析来看,我们可以借助“任何数与 (1) 的乘积均为其本身”的性质定义模意义下的乘法逆元。

    故其定义为:如果说 (a) 在模 (p) 意义下的乘法逆元是 (x),那么 (ax equiv 1 pmod{p})

    我们通常将 (a) 的乘法逆元记作 (a^{-1})

    如同 (0) 没有倒数一样, (0) 也没有乘法逆元。

    不难发现,(a) 在模 (p) 意义下的乘法逆元均为 ([1,p - 1]) 中的整数。

    逆元存在吗

    但是,我们一直都没用考虑一个问题:乘法逆元一定存在吗?

    如果 (x)(a) 在模 (p) 意义下的乘法逆元,则 (ax equiv 1 pmod{p}),这个方程可以写成 (ax+pk=1) ((kinmathbb{Z}))

    还记得上面说的线性组合集的性质吗?对于 (a,p) 的线性组合集 (S={zmid ax+py, xinmathbb{Z},yinmathbb{Z}}),集合中最小的正元素为 (gcd(a,p))。若方程 (ax+pk=1) 有解,说明 (gcd(a,p)=1),即 (a,p) 互质。

    实际上,(a) 在模 (p) 意义下的乘法逆元存在的充分必要条件是 (a,p) 互质。这也在一定程度上解释了大多数题目模数为质数的原因:(设模数为 (p))可以保证在 ([1,p−1) 中的所有整数都有模 (p) 意义下的逆元。

    求逆元的方法

    求逆元实际上就是求方程 (ax+pk=1=gcd(a,p)) 的整数解,套扩展欧几里得就可以了。

    求逆元还有别的方法,详见【洛谷日报#205】乘法逆元

    中国剩余定理

    「物不知数」问题

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

    即求满足以下条件的整数:除以 (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) 可求解如下形式的一元线性同余方程组(其中 (m_1, m_2, cdots, m_k) 两两互质):

    [egin{cases} x &equiv a_1 pmod {m_1} \ x &equiv a_2 pmod {m_2} \ &vdots \ x &equiv a_k pmod {m_k} \ end{cases} ]

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

    原理是什么?

    具体数字

    就以解这个方程为例(这里 (3,5,7) 是两两互质的)

    [egin{cases} xequiv 2 pmod 3\ xequiv 3 pmod 5\ xequiv 2 pmod 7 end{cases} ]

    第一个:

    我们发现 (15) 是一个很有意思的数,它是 (3,5) 的倍数而且模 (7)(1),于是 (15m) ((m<7))(3,5) 的倍数,并且模 (7)(m)

    另两个有意思的数是 (21)(70)(注意不是 (35)(35mod 3=2,70mod 3=1)),所以 (70 imes 2+21 imes 3+15 imes 2) 就是同余方程组的一个解。

    有没有别的解呢?假设 (x+c)(x) 均为同余方程组的解,那么 (x+cequiv xpmod 3),所以 (3mid c),同理有 (5mid c, 7mid c),所以 (c) 最小取 (operatorname{lcm}(3,5,7)=3 imes 5 imes 7=105)(3,5,7) 互质)。当两个数相差不是 (105) 的倍数时,它们的差模 (3,5,7) 不可能都相同。所以解在模 (105) 的意义下是存在且唯一的。

    我想你可能有的问题是万一如 (15,21,70) 这样的有趣的数找不到怎么办? 事实上这不可能发生。

    对于一般的问题

    [egin{cases} xequiv 1 pmod {m_1}\ xequiv 0 pmod {m_2,m_3,cdots,m_k} end{cases} ]

    第二个方程的解显然是 (x=k(m_2m_3cdots m_k)) ((kinmathbb{Z})),代入第一个方程得 (k(m_2m_3cdots m_k)equiv 1 pmod {m_1}),所以 (k)(m_2m_3cdots m_k) 在模 (m_1) 意义下的乘法逆元,而 (m_2m_3cdots m_k)(m_1) 互质,因此乘法逆元存在。

    拓展阅读:用抽屉原理证明方程组有解

    我们证明在 (0,1,2,cdots,104) 中原方程组有且仅有一个解. 事实上,对于每一个上述范围中的 (x) ,我们计算 (x) 分别除以 (3,5,7) 的余数 (a,b,c) ,这里 (a)(0,1,2)(b)(0,1,2,3,4)(c)(0,1,2,3,4,5,6) . 所以余数数组 ((a,b,c)) 的可能一共有 (105) 种.

    然而容易发现对于该范围内的任两个数,他们除以 (3,5,7) 的余数不可能完全相同. 所以 (105) 个数组恰好每一种被取到一次. 这样就完成了存在性的证明.

    符号化

    求解方程组

    [egin{cases} x &equiv a_1 pmod {m_1} \ x &equiv a_2 pmod {m_2} \ &vdots \ x &equiv a_k pmod {m_k} \ end{cases} ]

    (其中 (m_1,m_2,ldots ,m_k) 两两互质)

    的核心是找到一列数 (b_1,b_2,ldots ,b_k) 使得

    [egin{cases} b_1 &equiv 1 pmod {m_1} \ b_1 &equiv 0 pmod {m_2} \ &vdots \ b_1 &equiv 0 pmod {m_k} \ end{cases} , egin{cases} b_2 &equiv 0 pmod {m_1} \ b_2 &equiv 1 pmod {m_2} \ &vdots \ b_2 &equiv 0 pmod {m_k} \ end{cases} ,cdots, egin{cases} b_k &equiv 0 pmod {m_1} \ b_k &equiv 0 pmod {m_2} \ &vdots \ b_k &equiv 1 pmod {m_k} \ end{cases} ]

    那么 (x=a_1b_1+a_2b_2+cdots +a_kb_k) 就是原方程组的一个解。

    (M=prod_{i=1}^n m_i)​,并设 (M_i=dfrac{M}{m_i})​,(t_i={M_i}^{-1})(M_i)​ 在模 (m_i)​ 的意义下的乘法逆元,那么 (b_i=M_icdot t_i),由此可以得到方程在模 (M) 意义下的唯一解:

    [x=left(sum_{i=1}^n a_it_iM_i ight)mod M ]

  • 相关阅读:
    线程学习笔记(一)
    进程间通信
    管道通信操作
    在程序中执行shell命令
    进程控制(一)
    Makefile文件学习总结
    进程学习笔记
    C#不安全代码和指针
    Unity3D ShaderLab 修改渲染队列进行深度排序
    Unity3D ShaderLab 透明裁剪着色器
  • 原文地址:https://www.cnblogs.com/1024th/p/14349347.html
Copyright © 2011-2022 走看看