扩展欧几里得算法、乘法逆元与中国剩余定理

本文深入解析数论核心概念,包括整除、同余、扩展欧几里得算法及乘法逆元,阐述中国剩余定理原理与解题技巧,适合信竞学习者。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

前言

本文从定义与定理说起,详细地讲解了扩展欧几里得算法和乘法逆元的推导与应用。

本文尽量把推导的步骤细化,并罗列所需基础知识,比网络上一些博客更加详尽,希望能够为大家的 数论 信竞学习带来帮助。

如果发现推导错误,或者有更好的推导方法,请及时告知博主。

未加特殊说明时,本文中字母代表的均为整数。

定义、定理和部分证明

整除

定义
  • a , b ∈ Z a,b\in\Z a,bZ a ≠ 0 a\neq0 a=0. 如果存在 q ∈ Z q\in\Z qZ,使得 b = a q b=aq b=aq,那么就说 b b b 可被 a a a 整除,记做 a ∣ b a\mid b ab ,且称 b b b a a a倍数 a a a b b b约数. b b b 不能被 a a a 整除就记做 a ∤ b a\nmid b ab.
定理
  • a ∣ b ⇔ − a ∣ b ⇔ a ∣ − b ⇔ ∣ a ∣ ∣ ∣ b ∣ a\mid b \Leftrightarrow -a\mid b \Leftrightarrow a\mid -b \Leftrightarrow |a| \mid |b| abababab. (1)

  • a ∣ b a\mid b ab a ∣ c ⇒ a\mid c \Rightarrow ac对任意的 x , y ∈ Z x,y\in\Z x,yZ a ∣ b x + c y a\mid bx+cy abx+cy (2)

定理的证明
  • b = a q ⇔ b = ( − a ) ( − q ) ⇔ − b = a ( − q ) ⇔ ∣ b ∣ = ∣ a ∣ ∣ q ∣ b=aq \Leftrightarrow b=(-a)(-q) \Leftrightarrow -b=a(-q) \Leftrightarrow |b|=|a||q| b=aqb=(a)(q)b=a(q)b=aq,可证明(1)
  • b = a q 1 b=aq_1 b=aq1 c = a q 2 c=aq_2 c=aq2 可推出 b x + c y = a ( q 1 x + q 2 y ) bx+cy=a(q_1x+q_2y) bx+cy=a(q1x+q2y),则 a ∣ b x + c y a\mid bx+cy abx+cy ,(2)成立

同余

定义
  • m ≠ 0 m\neq0 m=0. 若 m ∣ a − b m|a-b mab,即 a − b = k m a-b=km ab=km,则称 m m m 为模, a a a 同余于 b b b m m m 以及 b b b a a a对模 m m m的剩余,记做:

a ≡ b   ( m o d   m ) a   m o d   m = b a\equiv b\ (mod\ m) \\ a\ mod\ m=b ab (mod m)a mod m=b

​ 不然,则称** a a a 不同余于 b b b m m m b b b 不是 a a a 对模 m m m 的剩余**,记做:
a ≠ b   ( m o d   m ) a   m o d   m ≠ b a\neq b\ (mod\ m) \\ a\ mod\ m\neq b a=b (mod m)a mod m=b
​ (注:上面第一条应该是在同余符号 ≡ \equiv 上打斜杠,然而我打不出来这个符号)

同余的性质
  • 自反性: a ≡ a   ( m o d   m ) a\equiv a\ (mod\ m) aa (mod m)
  • 对称性: a ≡ b   ( m o d   m ) ⇔ b ≡ a   ( m o d   m ) a\equiv b\ (mod\ m) \Leftrightarrow b\equiv a\ (mod\ m) ab (mod m)ba (mod m)
  • 传递性:如果 a ≡ b   ( m o d   m ) a\equiv b\ (mod\ m) ab (mod m) 并且 b ≡ c   ( m o d   m ) b\equiv c\ (mod\ m) bc (mod m) ,那么 a ≡ c   ( m o d   m ) a\equiv c\ (mod\ m) ac (mod m)
同余的运算律
  • m m m 意义下, 如果 a ≡ b a\equiv b ab 并且 c ≡ d c\equiv d cd,那么 a + c ≡ b + d a+c\equiv b+d a+cb+d (1)
  • m m m 意义下, 如果 a ≡ b a\equiv b ab 并且 c ≡ d c\equiv d cd,那么 a c ≡ b d ac\equiv bd acbd (2)
运算律的证明
  • (1)由 m ∣ a − b m\mid a-b mab m ∣ c − d m\mid c-d mcd 可以得到 m ∣ ( a − c ) + ( c − d ) m\mid(a-c)+(c-d) m(ac)+(cd) 也就是 m ∣ ( a + c ) − ( b + d ) m\mid (a+c)-(b+d) m(a+c)(b+d)

a + c ≡ b + d   ( m o d   m ) a+c \equiv b+d\ (mod\ m) a+cb+d (mod m)

  • (2)由 a − b = k 1 m a-b=k_1m ab=k1m c − d = k 2 m c-d=k_2m cd=k2m 可得到 a = b + k 1 m a=b+k_1m a=b+k1m c = d + k 2 m c=d+k_2m c=d+k2m

那么 a c = ( b + k 1 m ) ( d + k 2 m ) = b d + b k 2 m + d k 1 m + k 1 k 2 m ac=(b+k_1m)(d+k_2m)=bd+bk_2m+dk_1m+k_1k_2m ac=(b+k1m)(d+k2m)=bd+bk2m+dk1m+k1k2m

那么 a c − b d = ( b k 2 + d k 1 + k 1 k 2 ) m ac-bd=(bk_2+d_k1+k_1k_2)m acbd=(bk2+dk1+k1k2)m 也就是 m ∣ a c − b d m\mid ac-bd macbd,也就是 a c ≡ b d   ( m o d   m ) ac \equiv bd\ (mod\ m) acbd (mod m)

扩展欧几里得算法

详情请见《算法竞赛 入门到进阶》P159-P160 (或其他算法书)关于扩展欧几里得算法的部分

代码模板

扩展欧几里得算法可以写成这样:

void exgcd(int a,int b,int &x,int &y) //x y是解,需要在每一次计算中改变
{
	if(b==0)
	{
		x=1,y=0;
		return;
	} 
	exgcd(b,a%b,x,y);
	int tmp=x;
	x=y;
	y=tmp-(a/b)*y;
} 

如果不想理解其中为什么要写&x和&y,也可以写成这样(我不知道有没有人会这么写)

pair<int,int> exgcd(int a,int b)
{
	if(b==0)return make_pair(1,0);
	pair<int,int> t=exgcd(b,a%b);
	pair<int,int> res;
	res.first=t.second;
	res.second=t.first-(a/b)*t.second;
	return res;
}

算法详解

下面我们来解释一下:

如果不看对于x和y的运算部分,那么这个函数就是普通的欧几里得算法,求的是 g c d ( a , b ) gcd(a,b) gcd(a,b)

我们想要求 a x + b y = g c d ( a , b ) ax+by=gcd(a,b) ax+by=gcd(a,b)的一组特解,那么显然在最底层的时候(也就是正好求得 g c d ( a , b ) gcd(a,b) gcd(a,b) 的时候,此时函数中的 a = g c d ( a , b ) a=gcd(a,b) a=gcd(a,b) ,函数中的 b = 0 b=0 b=0),这个特解就是
{ x = 1 y = 0 \begin{cases} x=1\\ y=0 \end{cases} {x=1y=0
因为$ 1gcd(a,b)+00=gcd(a,b)$。

因此我们知道了这个简单的特解,如何倒推回去,找到我们需要的特解呢?

也就是说,当我们运行到第9行(指第一块代码)时,

我们已经解出了 b x 1 + ( a   m o d   b ) y 1 = g c d ( b , a   m o d   b ) = g c d ( a , b ) bx_1+(a\ mod\ b)y_1=gcd(b,a\ mod\ b)=gcd(a,b) bx1+(a mod b)y1=gcd(b,a mod b)=gcd(a,b) 的解,

我们怎么通过这个特解,找到 a x 2 + b y 2 = g c d ( a , b ) ax_2+by_2=gcd(a,b) ax2+by2=gcd(a,b) 的解呢?

我们不妨把 a   m o d   b a\ mod\ b a mod b 写成 a − ⌊ a / b ⌋ ∗ b a-\lfloor a/b\rfloor*b aa/bb (向下取整,在C++中,如果变量 a , b a,b a,b都是 i n t int int类型,那么自动向下取整)

我们进行一些推导
{ b x 1 + ( a − ⌊ a / b ⌋ ∗ b ) y 1 = g c d ( a , b ) a x 2 + b y 2 = g c d ( a , b ) ⇒ a x 2 + b y 2 = b x 1 + ( a − ⌊ a / b ⌋ ∗ b ) y 1 ⇒ a x 2 + b y 2 = a y 1 + ( x 1 − ⌊ a / b ⌋ y 1 ) b ⇒ { x 2 = y 1 y 2 = x 1 − ⌊ a / b ⌋ y 1 \begin{cases} bx_1+(a-\lfloor a/b\rfloor*b)y_1=gcd(a,b)\\ ax_2+by_2=gcd(a,b) \end{cases} \\ \Rightarrow ax_2+by_2=bx_1+(a-\lfloor a/b\rfloor*b)y_1 \\ \Rightarrow ax_2+by_2=ay_1+(x_1-\lfloor a/b\rfloor y_1)b \\ \Rightarrow \begin{cases} x_2=y_1\\ y_2=x_1-\lfloor a/b\rfloor y_1 \end{cases} {bx1+(aa/bb)y1=gcd(a,b)ax2+by2=gcd(a,b)ax2+by2=bx1+(aa/bb)y1ax2+by2=ay1+(x1a/by1)b{x2=y1y2=x1a/by1
这样我们就求出来了 x 1 , y 1 x_1,y_1 x1,y1 x 2 , y 2 x_2,y_2 x2,y2的对应关系,就可以一步一步地求出来 a x + b y = g c d ( a , b ) ax+by=gcd(a,b) ax+by=gcd(a,b)的特解了。

乘法逆元

详情请见《算法竞赛 入门到进阶》P161-P162 (或其他算法书)关于乘法逆元的部分

求解逆元

定义

  • a a a m m m 的逆,是方程 a x ≡ 1   ( m o d   m ) ax\equiv 1\ (mod\ m) ax1 (mod m)的解。

首先 a x ≡ 1   ( m o d   m ) ⇔ a x − 1 = y m ⇔ a x + m y = 1 ax\equiv 1\ (mod\ m) \Leftrightarrow ax-1=ym \Leftrightarrow ax+my=1 ax1 (mod m)ax1=ymax+my=1 (这里的 y y y 只是我们设的一个未知数)

那么我们发现 a x + m y = 1 ax+my=1 ax+my=1 刚好可以用扩展欧几里得算法求解。

乘法逆元的作用

有时我们需要求解 ( a b )   m o d   m \Big( \frac{a}{b} \Big) \ mod\ m (ba) mod m,但是苦于 a b \frac{a}{b} ba 的精度不够,因此我们需要另寻一个办法。而运用逆元可以很方便地解决这个问题。

k k k 是模 m m m 意义下 b b b 的逆元,也就是说 k b ≡ 1   ( m o d   m ) kb\equiv 1\ (mod\ m) kb1 (mod m) ,也就是 b k   m o d   m = 1 bk\ mod\ m=1 bk mod m=1 ,则有如下的推导:
( a b )   m o d   m = ( a b )   m o d   m ∗ 1 = ( a b )   m o d   m ∗ ( ( b k )   m o d   m ) = ( a b b k )   m o d   m = ( a k )   m o d   m \big(\frac{a}{b}\big)\ mod\ m=\big(\frac{a}{b}\big)\ mod\ m*1=\big(\frac{a}{b}\big)\ mod\ m*((bk)\ mod\ m)=\big(\frac{a}{b}bk\big)\ mod\ m=\big( ak\big)\ mod\ m (ba) mod m=(ba) mod m1=(ba) mod m((bk) mod m)=(babk) mod m=(ak) mod m
我们巧妙地把除法化为了乘法,避免了精度问题。

中国剩余定理

出处

对于中国剩余定理,我们决定先不看那又长又难的定义。

不如我们先来讲个故事吧:

中国剩余定理,即孙子定理,出自《孙子算经》。

《孙子算经》(成书于1500年前左右)是我国古代一本重要的数学著作,大家耳熟能详的鸡兔同笼问题就出自于此。就在《孙子算经》上,有一则引出今天所讲的定理的问题:

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

意思就是说,有一个数,模3余2,模5余3,模7余2,让我们求出这个数是多少。

我们可以先用暴力枚举尝试一下:

模3余2的数:2,5,8,11,14,17,20,23,26,29…

模5余3的数:3,8,13,18,23,28,33…

模7余2的数:2,9,16,23,30…

很快就找到了答案,就是23,不过需要注意的是,这个数并不唯一,而23是这个问题的最小整数解。

聪明绝顶的古人们对于这道题,想出了一个绝妙的口诀:

三人同行古来稀,五树梅花廿一枝,七子团圆正半月,除百零五便得知。

(古稀就是70岁,廿一为21,半月是15天)

意思就是说用 70 70 70 乘上对 3 3 3 的余数 2 2 2,用 21 21 21 乘上对 5 5 5 的余数 3 3 3,用 15 15 15 乘上对 7 7 7 的余数 2 2 2,结果是:
2 ∗ 70 + 3 ∗ 21 + 2 ∗ 15 = 233 ( 2 ∗ 70 + 3 ∗ 21 + 2 ∗ 15 )   m o d   105 = 23 2*70+3*21+2*15=233\\ (2*70+3*21+2*15)\ mod\ 105=23 270+321+215=233(270+321+215) mod 105=23
和我们的答案一致。不过这里的 70 , 21 , 15 70,21,15 70,21,15是怎么来的呢?

我们拿 70 70 70举例,发现 5 ∣ 70 5|70 570 并且 7 ∣ 70 7|70 770 ,而 70 ≡ 1   ( m o d   3 ) 70\equiv 1\ (mod\ 3) 701 (mod 3) ,这也就是说 70 70 70乘多少倍,不会产生 5 , 7 5,7 5,7的余数,但是会给 3 3 3产生余数, 70 70 70 3 3 3的余数是 1 1 1 70 70 70乘多少倍,就会对模 3 3 3产生多少倍的余数。这样,我们轻轻松松地就控制了 3 3 3的余数部分。同理,我们用 21 21 21轻松地控制了 5 5 5的余数,用 15 15 15轻松地控制了 7 7 7的余数。

而这并不是最小的解,我们只需要模 3 , 5 , 7 3,5,7 3,5,7的最小公倍数 105 105 105(对三个数都不会产生余数),就可以求出来最小正整数解。

然而…

5 ∗ 7 = 35 35 ∗ 2 = 70 3 ∗ 7 = 21 21 ∗ 1 = 21 3 ∗ 5 = 15 15 ∗ 1 = 15 5*7=35\quad35*2=70\\3*7=21\quad21*1=21\\3*5=15\quad15*1=15 57=35352=7037=21211=2135=15151=15
有的乘了 2 2 2,有的乘了 1 1 1,我怎么知道如何才能求出来最终满足对于其他数都没有余数,而只对自己对应的数产生1的余数的那个数呢?其实,如果你认真阅读乘法逆元部分,你会很敏感地发现 2 ∗ 35 ≡ 1   ( m o d   3 ) 2*35\equiv1\ (mod\ 3) 2351 (mod 3),乘的倍数,正是 35 35 35 3 3 3意义下的逆!

中国剩余定理的内容

这下子我们终于可以给出中国剩余定理的内容了:

设正整数 m 1 , m 2 , . . . , m k m_1,m_2,...,m_k m1,m2,...,mk是两两既约(互素,若 a a a b b b 互素,则 a a a b b b 的最大公约数为 1 1 1 )的正整数,那么对于任意整数 a 1 , . . . , a k a_1,...,a_k a1,...,ak,一次同余方程组
x ≡ a j   ( m o d   m j ) , 1 ≤ j ≤ k x\equiv a_j\ (mod\ m_j),\quad1\leq j\leq k xaj (mod mj),1jk
在模 M = m 1 ⋅ m 2 ⋅ . . . ⋅ m k M=m_1·m_2·...·m_k M=m1m2...mk(也就是他们的最小公倍数)的意义下,有且仅有一个解,

这个解是
x = ( ∑ j = 1 k a j M j M j − 1 )   m o d   m x=(\sum_{j=1}^k a_jM_jM_j^{-1})\ mod\ m x=(j=1kajMjMj1) mod m
其中 M j = M / m j M_j=M/m_j Mj=M/mj M j − 1 M_j^{-1} Mj1 M j M_j Mj在模 m j m_j mj下的逆。

通过这个方法,我们可以快速地求出一些长成这样的一次同余方程组的解。

引用

  1. 《初等数论》第三版,潘承洞 潘承彪著,第一章 整除理论,第三章 同余的基本知识
  2. Luogu P1082 同余方程 题解区
  3. 《算法竞赛 入门到进阶》罗勇军 郭卫斌著 第8章 数学
  4. bilibili, 视频 《中国古代稀有的一个数学定理,孙子定理是什么?…》 李永乐

例题

Luogu P1082 同余方程 (本题也可以用欧拉函数求解,感兴趣的同学可以看题解)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值