数论——中国剩余定理及其扩展详解

文章目录

        • 概述
        • 中国剩余定理扩展
          • 例题
        • 总结

概述

  1. 引入:

    一元线性同余方程组问题最早可见于中国南北朝时期(公元5世纪)的数学著作《孙子算经》卷下第二十六题,叫做“物不知数”问题,原文如下:
    有物不知其数,三三数之剩二,五五数之剩三,七七数之剩二。问物几何?
    即,一个整数除以三余二,除以五余三,除以七余二,求这个整数。《孙子算经》中首次提到了同余方程组问题,以及以上具体问题的解法,因此在中文数学文献中也会将中国剩余定理称为孙子定理。

  2. 概述:
    孙子定理,又称中国剩余定理或中国余数定理,是数论中的一个关于一元线性同余方程组的定理,说明了一元线性同余方程组有解的准则以及求解方法。

  3. 内容
    用现代数学的语言来说明的话,中国剩余定理给出了以下的一元线性同余方程组:数论——中国剩余定理及其扩展详解_第1张图片
    有解的判定条件,并用构造法给出了在有解情况下解的具体形式。

    中国剩余定理说明:假设整数 m 1 , m 2 , . . . , m n m_1, m_2, ... , m_n m1,m2,...,mn其中任两数互质,则对任意的整数: a 1 , a 2 , . . . , a n a_1, a_2, ... , a_n a1,a2,...,an,方程组 ( S ) {\displaystyle (S)} (S)有解,并且通解可以用如下方式构造得到:

    1. M = m 1 × m 2 × ⋯ × m n = ∏ i = 1 n m i {\displaystyle M=m_{1}\times m_{2}\times \cdots \times m_{n}=\prod _{i=1}^{n}m_{i}} M=m1×m2××mn=i=1nmi是整数 m 1 , m 2 , . . . , m n m_1, m_2, ... , m_n m1,m2,...,mn的乘积,并设 M i = M / m i ,      ∀ i ∈ { 1 , 2 , ⋯   , n } M i = M / m i ,      ∀ i ∈ { 1 , 2 , ⋯   , n } {\displaystyle M_{i}=M/m_{i},\;\;\forall i\in \{1,2,\cdots ,n\}}M_i = M/m_i, \; \; \forall i \in \{1, 2, \cdots , n\} Mi=M/mi,i{1,2,,n}Mi=M/mi,i{1,2,,n},即 M i {\displaystyle M_{i}} Mi是除了 m i m_i mi以外的n − 1个整数的乘积。
    2. t i = M i − 1 为 M i {\displaystyle t_{i}=M_{i}^{-1}}为{\displaystyle M_{i}} ti=Mi1Mi m i 的 逆 元 : t i M i ≡ 1 ( m o d m i ) ,      ∀ i ∈ { 1 , 2 , ⋯   , n } . {\displaystyle m_{i}}的逆元:{\displaystyle t_{i}M_{i}\equiv 1{\pmod {m_{i}}},\;\;\forall i\in \{1,2,\cdots ,n\}.} mitiMi1(modmi),i{1,2,,n}.
    3. 方 程 组 ( S ) 的 通 解 形 式 为 : 方程组{\displaystyle (S)}的通解形式为: (S) x = a 1 t 1 M 1 + a 2 t 2 M 2 + ⋯ + a n t n M n + k M = k M + ∑ i = 1 n a i t i M i , k ∈ Z . {\displaystyle x=a_{1}t_{1}M_{1}+a_{2}t_{2}M_{2}+\cdots +a_{n}t_{n}M_{n}+kM=kM+\sum _{i=1}^{n}a_{i}t_{i}M_{i},\quad k\in \mathbb {Z} .} x=a1t1M1+a2t2M2++antnMn+kM=kM+i=1naitiMi,kZ. 在 模 M 的 意 义 下 , 方 程 组 ( S ) 只 有 一 个 解 : x = ∑ i = 1 n a i t i M i . 在模{\displaystyle M}的意义下,方程组{\displaystyle (S)}只有一个解:{\displaystyle x=\sum _{i=1}^{n}a_{i}t_{i}M_{i}.} M(S)x=i=1naitiMi.
  4. 证明:
    数论——中国剩余定理及其扩展详解_第2张图片

def exgcd(a, b) :
	if b == 0 :
	return 1, 0, a
	x, y, d = exgcd(b, a % b)
	return y, x - (a // b) * y, d
def CRT(a, b) : #a, b分别是模数和余数
	M = 1
	X = 0
	for i in a :
		M *= i
	for i in zip(a, b) :
		w = M // i[0]
		x, y, d = exgcd(w, i[0])
		X = (X + x * w * i[1]) % M	
	return (X % M + M) % M

中国剩余定理扩展

求解模数不互质情况下的线性方程组

  1. 原理说明:
    普通中国剩余定理要求所有的模数 m i m_i mi互素,如果不互素就需要使用扩展中国剩余定理
    x ≡ a 1 ( m o d m 1 ) {\displaystyle x\equiv a_1{\pmod {m_{1}}}} xa1(modm1) —— (1)
    x ≡ a 2 ( m o d m 2 ) {\displaystyle x\equiv a_2{\pmod {m_{2}}}} xa2(modm2) ——(2)
    . . . . .... ....
    x ≡ a n ( m o d m n ) {\displaystyle x\equiv a_n{\pmod {m_{n}}}} xan(modmn)
    对于(1)、(2)式,可得 x = m 1 x 1 + a 1 x = m_1x_1+a_1 x=m1x1+a1 x = m 2 x 2 + a 2 x = m_2x_2+a_2 x=m2x2+a2
    可以推出 m 1 x 1 + a 1 = m 2 x 2 + a 2 m_1x_1 + a_1 = m_2x_2 + a_2 m1x1+a1=m2x2+a2-> m 1 x 1 = ( a 2 − a 1 ) + m 2 x 2 m_1x_1 = (a_2 - a_1) + m_2x_2 m1x1=(a2a1)+m2x2
    如果该式成立则 g c d ( m 1 , m 2 ) ∣ ( a 2 − a 1 ) gcd(m_1,m_2) | (a_2 - a_1) gcd(m1,m2)(a2a1)
    -> m 1 x 1 = ( a 2 − a 1 ) ( m o d   m 2 ) m_1x_1 = (a_2 - a_1) (mod\ m_2) m1x1=(a2a1)(mod m2)
    要求x最小,即求 x 1 x_1 x1最小,使用扩展欧几里得算法 e x g c d ( m 1 , m 2 ) exgcd(m_1, m_2) exgcd(m1,m2)求出最小公约数d以及 m 1 / d m_1/d m1/d的逆,最小 x 1 ≡ ( a 2 − a 1 ) / d ∗ ( m 1 / d ) − 1 ( m o d   m 2 / d ) x_1 \equiv(a_2 - a_1)/d * {(m_1/d)^{-1}}(mod \ m_2/d) x1(a2a1)/d(m1/d)1(mod m2/d)
    所以 x 1 取 最 小 值 , x 1 = [ ( a 2 − a 1 ) / d ∗ ( m 1 / d ) − 1 + m 2 / d ] % ( m 2 / d ) x_1取最小值,x1 = [(a_2 - a_1)/d * {(m_1/d)^{-1}} + m_2 / d] \% (m_2 / d) x1x1=[(a2a1)/d(m1/d)1+m2/d]%(m2/d)
    代入 x = m 1 x 1 + a 1 x = m_1x_1+a_1 x=m1x1+a1
    得到一个 x = ( m 1 ∗ m 2 ) / d ∗ k + a 1 + m 1 ∗ ( a 2 − a 1 ) / d ∗ ( m 1 / d ) − 1 x = (m_1 * m _2) / d * k + a_1 + m_1 * (a_2 - a_1)/d* {(m_1/d)^{-1}} x=(m1m2)/dk+a1+m1(a2a1)/d(m1/d)1
    则k可视为一个新的 x x x, a 1 + m 1 ∗ ( a 2 − a 1 ) / d ∗ ( m 1 / d ) − 1 a_1 + m_1 * (a_2 - a_1)/d* {(m_1/d)^{-1}} a1+m1(a2a1)/d(m1/d)1可视为新的a
例题

数论——中国剩余定理及其扩展详解_第3张图片

n = int(input())
def exgcd(a, b) :
	if b == 0 :
		return 1, 0, a
	x, y, g = exgcd(b, a % b)
	return y, x - (a // b) * y, g
x = 0
m1, a1 = map(int, input().split())

for i in range(n - 1):
	m2, a2 =  map(int, input().split())
	k1, k2, d = exgcd(m1, m2)
	k1 *= (a2 - a1) // d
	k1 = (k1 % (m2 // d) + (m2 // d)) % (m2 // d) ###求最小正整数
	x = k1 * m1 + a1
	m1 = abs(m1 * m2 // d)
	a1 = x
if x != -1 :
	x = (a1 % m1 + m1) % m1
print(x)

总结

中国剩余定理真孙子,太难啦,我要成孙子了。

你可能感兴趣的:(数据结构与算法,算法)