数论:从零到数论倒数/逆元(P1)

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档

前言

咳咳咳 这应该是本人的第一篇CSDN 希望接下来写小文章顺利

求解数论倒数其实是个老话题了 不过我觉得对我进行学习归纳以及用我这种小白都能听懂的解释讲解还是很有意义的 由于本篇确实讲的比较细反而有点冗杂 只能麻烦你自行跳转了

由于内容较多本文一刀两P 后半部分请参本人同名文章P2

引子

关于会选这个主题嘛…… 说来有些曲折 原先我所知道的求数论倒数(事实上我只有在组合数做数论除法或是求概率取模成整数时才用的到(都是对大素数取模也就没啥问题)) 一直都是用的费马小定理 前两天学习了拓展欧几里得才知道其实去求解一个线性不定方程就行了 突然感觉天有点塌(我还以为只能利用快速幂实现小费马) 以下相对从0开始 (九年义务教育基础知识就够 其余涉及的知识顶多是数论的基本定义和集合而已) 分别介绍这两种算法 (事实上我们在后面还会了解到欧拉定理并知道小费马其实就是欧拉定理的特殊情况)

回顾找逆元的原因

首先最基本的数论概念大家应该有 就是整数范围内讨论整除、同余与不定方程 在一个 m o d mod mod下对于加法乘法 加/乘法与取模运算顺序不影响结果 可除法就不一样了(不信的话你可以试试 如果答案是正确的那你真是幸运极了) 它常常会造成错误结果 (事实上如果你仅仅是使用模运算消去律这是十分严谨而无误的 请参考 附录 0 附录0 附录0)

背后的原理其实在于数论讨论的整数集常常对除法不封闭(否则我们就来到有理数集了) 这也正是我们为什么会用一门数论来讨论整除同余和不定方程

我们回忆日常中的除法 其实 a / b = a ⋅ b − 1 = a ⋅ 1 b a/b=a \cdot b^{-1}=a\cdot \frac{1}{b} a/b=ab1=ab1 所以我们考虑去找数论中的倒数 也就是逆元 如找 a a a a ′ a' a使得

a ⋅ a ′ ≡ 1 ( m o d   m ) a\cdot a' \equiv 1 \quad (mod\ m) aa1(mod m)

事实上按照这种方式求得 b ′ b' b那么我们就可以用 a ⋅ b ′ a·b' ab表示 a / b a/b a/b 能够求解

a ⋅ b ≡ x a ⋅ b ⋅ b ′ ≡ x ⋅ b ′ a ≡ x ⋅ b ′ \begin{gather} a\cdot b \equiv x \\ a\cdot b\cdot b' \equiv x\cdot b' \\ a \equiv x\cdot b' \end{gather} abxabbxbaxb

但不幸的是 大多数时候 在一个 m o d mod mod下常常有很多数不存在逆元(事实上贝祖定理和小费马/欧拉定理都向我们解释了关于逆元存在性的问题) 不过在 O I OI OI编码过程中肯定是保证存在的

至于什么时候需要同余除法呢 我已知的是组合数概率取模 (本人小白 还望指正)

本篇BLOG正式讲解如何求解数论乘法逆元

拓展欧几里得

相信大多数人应该都是最先接触这种方法 原因在于它容易理解 拓展欧几里得的实用性高 求乘法逆元只是它的一个小巧思 让我们从头开始吧

Tip: g c d ( a , b ) gcd(a,b) gcd(a,b)表示 a , b a,b a,b的最大公因数 由于 g c d ( 0 , 0 ) gcd(0,0) gcd(0,0)本身无意义 所以我们不讨论全为0的情况 以下默认不再强调不全为0

一般の欧几里得

欧几里得算法也就是辗转相除法 是求 g c d ( a , b ) gcd(a,b) gcd(a,b)的高效做法 平时做数学题也是该方法最好用

欧几里得的复杂度是对数级 O ( l o g n ) O(logn) O(logn) 这里我并不愿意证明 具体参附录 A .1 A.1 A.1

因为原理简单 所以先讲解辗转相除法的原理 (另外在[拓展欧几里得の实现]一节开头有另一种呈现 我也不知道哪版更适合你 你可以跳去阅读)

令 d = g c d ( a , b )   ,   a = d m   ,   b = d n   ( a > b ≥ 0 ) 那么 g c d ( m , n ) = 1 d ∣ ( d m − d n )  即  d ∣ ( a − b ) 因为 g c d ( m , n ) = 1  所以 g c d ( m − n , n ) 也为 1 也就是说 g c d ( a − b , b ) = g c d ( a , b ) = d 那么 a − b − b 等等也应符合 ( 保证不减到小于 0 ) 其实记 r = a   m o d   b   ( 你可以理解为一直作差 ) 最终有 g c d ( r , b ) = g c d ( a , b ) = d 同样你会有 g c d ( r , b   m o d   r ) = d \begin{align} &令d=gcd(a,b)\ ,\ a=dm\ ,\ b=dn \ (a>b\geq 0)\\ &那么gcd(m,n)=1 \\ &d\mid (dm-dn) \ 即\ d\mid (a-b) \\ &因为gcd(m,n)=1 \ 所以gcd(m-n,n)也为1 \\ &也就是说gcd(a-b,b)=gcd(a,b)=d \\ &那么a-b-b等等也应符合(保证不减到小于0)\\ \\ &其实记r=a\ mod\ b \ (你可以理解为一直作差)\\ &最终有gcd(r,b)=gcd(a,b)=d \\ &同样你会有gcd(r,b\ mod\ r)=d\\ \end{align} d=gcd(a,b) , a=dm , b=dn (a>b0)那么gcd(m,n)=1d(dmdn)  d(ab)因为gcd(m,n)=1 所以gcd(mn,n)也为1也就是说gcd(ab,b)=gcd(a,b)=d那么abb等等也应符合(保证不减到小于0)其实记r=a mod b (你可以理解为一直作差)最终有gcd(r,b)=gcd(a,b)=d同样你会有gcd(r,b mod r)=d

所以我们可以这样做

( 以下为迭代过程 请不要搞晕 ) 令 r = a   m o d   b 赋值 a = b , b = r 重复上述操作直到最后 b = 0   g c d ( a , 0 ) = a 此时的 a 就是原先的最大公因数 如果不写成迭代形式 这就是前后不断大数除以小数的过程 所以它才被称为辗转相除法 我们来试一个例子 : g c d ( 24 , 42 ) 第一步  r = 42   m o d   24   = 18  接着  a = 24 , b = 18 第二步  r = 24   m o d   18   = 6  接着  a = 18 , b = 6 第三步  r = 18   m o d   6   = 0  接着  a = 6 , b = 0 b = 0 结束了返回 a = 6 没错  g c d ( 24 , 42 ) = 6 \begin{align} &(以下为迭代过程 \ 请不要搞晕)\\ &令r=a\ mod\ b \\ &赋值a=b,b=r\\ &重复上述操作直到最后b=0 \ gcd(a,0)=a \\ &此时的a就是原先的最大公因数 \\ &如果不写成迭代形式 \ 这就是前后不断大数除以小数的过程 \\ &所以它才被称为辗转相除法 \\ \\ &我们来试一个例子:gcd(24,42) \\ &第一步\ r=42\ mod\ 24\ =18\ 接着\ a=24,b=18\\ &第二步\ r=24\ mod\ 18\ =6\ 接着\ a=18,b=6 \\ &第三步\ r=18\ mod\ 6\ =0\ 接着\ a=6,b=0 \\ &b=0结束了返回a=6 \\ &没错\ gcd(24,42)=6 \\ \end{align} (以下为迭代过程 请不要搞晕)r=a mod b赋值a=b,b=r重复上述操作直到最后b=0 gcd(a,0)=a此时的a就是原先的最大公因数如果不写成迭代形式 这就是前后不断大数除以小数的过程所以它才被称为辗转相除法我们来试一个例子:gcd(24,42)第一步 r=42 mod 24 =18 接着 a=24,b=18第二步 r=24 mod 18 =6 接着 a=18,b=6第三步 r=18 mod 6 =0 接着 a=6,b=0b=0结束了返回a=6没错 gcd(24,42)=6

这里还有一个例子 求 g c d ( 868 , 308 ) 求gcd(868,308) gcd(868,308) 它的结果为 28 28 28 我把它留给你来手动做 我相信你能很出色的完成的

我们可以很容易的写出欧几里得函数 事实上<cmath>头文件内自带__gcd(a,b) 不过它只支持 i n t int int数据 大多是时候请手写吧 你会用得上的

inline int gcd(int a,int b)
{
	a=abs(a),b=abs(b);//正负性不影响公因数 但我们还是统一换成正整数讨论
	if (a<b) swap(a,b);//保证a>b
	int r;
	while (b)
		r=a%b,
		a=b,b=r;
	return a; 
} 

裴蜀定理/贝祖定理

贝祖是拓展欧几里得的原理 只不过在这节讲解贝祖时只有数学了

反过来说拓展欧几里得正是贝祖的代码实现

我们先来看一个例子 关于(s,t)的不定方程
4 s + 6 t = 2 4s+6t=2 4s+6t=2
有没有整数解呢?你很容易看出来是存在的 而且似乎你还列举不完 ( − 1 , 1 ) (-1,1) (1,1)就是一个解

那么关于

4 s + 6 t = 3 4s+6t=3 4s+6t=3

呢?如果你直接试你会发现试不出来 或者讨论奇偶性你一眼就能看出来这是无解的 事实上 你可以用 t t t的代数式表示 s s s

s = 3 − 6 t 4 s=\frac{3-6t}{4} s=436t

再说明右侧取不到整数也是可以的 当然你大概不好证明 再比如下面这两个极端

204 s + 156 t = 138 204s+156t=138 204s+156t=138
187 s + 143 t = 165 187s+143t=165 187s+143t=165

是否有整数解 你在想瞪眼看出来就非常非常困难了 (如果你在还没学习贝祖的情况下仅凭数感就能判断 那你真的很厉害了 这一节的内容一定难不倒你) 事实上前一个无解 后一个有解且有无数多个其中一个是 (-45,60)

甚至是下面这个丧心病狂的三元一次不定方程

5978 s + 7442 t + 8906 w = 1464 5978s+7442t+8906w=1464 5978s+7442t+8906w=1464

我认为只有天才才能直接看出来有没有整数解了(事实上正确做法是对系数质因数分解 求 g c d gcd gcd什么的 可这又是贝祖正要教我们做的) 它是有解的其中一个解是 ( 888 , − 696 , 0 ) (888,-696,0) (888,696,0)

接下来我们会学习贝祖定理 以便判断这些不定方程是否有整数解 有什么整数解

基本贝祖定理

贝祖定理(Bézout’s Identity)事实上只由贝祖整合 定理内容早已存在:

对于整数 a , b a,b a,b给出不定方程

a s + b t = p as+bt=p as+bt=p

使得有整数解 ( s , t ) (s,t) (s,t)的最小正整数 p = g c d ( a , b ) p=gcd(a,b) p=gcd(a,b) (当然还有很多其他表述)

证明:

我们令 p p p为满足 ( s , t ) (s,t) (s,t)为整数的最小正整数 令 d = g c d ( a , b ) d=gcd(a,b) d=gcd(a,b)

a / p = q + r 即 a = p q + r ( 0 ≤ r < p ) a/p=q+r即a=pq+r \quad (0 \leq r < p) a/p=q+ra=pq+r(0r<p)

a = p q + r = ( a s + b t ) q + r a = a s q + b t q + r r = a ( 1 − s q ) + b ( − t ) 这个式子其实回到了我们原不定方程 其中 ( 1 − s q ) 和 ( − t ) 都为整数 说明 r 也是满足整数解的整数 ( 注意我没有说它为正 ) 如果 r > 0 则按照 p 的假设 有 r ≥ p  又不符合 r 的定义 ( 0 ≤ r < p ) 则 r = 0 即 p ∣ a  同理  p ∣ b 则 p 为 a , b 公因数 有 p ∣ d 对于原代数式一定有 d ∣ ( a s + b t )  即 d ∣ p 则 d ∣ p  且  p ∣ d 即 d = p \begin{align} &a=pq+r=(as+bt)q+r \\ &a=asq+btq+r \\ &r=a(1-sq)+b(-t) \\ &这个式子其实回到了我们原不定方程\ 其中(1-sq)和(-t)都为整数 \\ &说明r也是满足整数解的整数(注意我没有说它为正) \\ &如果r>0则按照p的假设\ 有r\geq p \ 又不符合r的定义(0 \leq r < p) \\ &则r=0\\ &即p\mid a \ 同理\ p\mid b \\ &则p为a,b公因数\ 有 p\mid d \\ \\ &对于原代数式一定有 \\ &d\mid (as+bt) \ 即d\mid p \\ &则d\mid p \ 且\ p\mid d \\ &即d=p \end{align} a=pq+r=(as+bt)q+ra=asq+btq+rr=a(1sq)+b(t)这个式子其实回到了我们原不定方程 其中(1sq)(t)都为整数说明r也是满足整数解的整数(注意我没有说它为正)如果r>0则按照p的假设 rp 又不符合r的定义(0r<p)r=0pa 同理 pbpa,b公因数 pd对于原代数式一定有d(as+bt) dpdp  pdd=p

这一段证明对你应该没有难点 然后我们来探究一些贝祖的拓展/引理

贝祖定理の小拓展

二元一次不定方程の解

接下来我们来看看二元一次不定方程什么时候有解 (解的存在性判断) 以及都有什么解 (解集的表示)

(以防你在下文迷糊了 我需要提醒你 事实上这一节有一个小错误 如果我们要讨论解集而不仅仅是解的存在性判断 必须严格符合二元一次不定方程 即系数其实都不为0 否则会退化为一个一元一次方程和毫无关系的另一个元 你可以试着推导一下这种特殊情况的解集)

我们来看贝祖的一般正式形式

a s + b t = d ( d = g c d ( a , d ) ) as+bt=d \quad (d=gcd(a,d)) as+bt=d(d=gcd(a,d))

如果存在一个解 ( s 0 , t 0 ) (s_0,t_0) (s0,t0) 其实通过最小公倍数不难想到解集为(事实上这并不严谨 严谨的推导参附录 A .2 A.2 A.2)

{ ( s , t ) ∣   s = s 0 + k ( b / d ) , t = t 0 − k ( a / d ) , k ∈ Z } \{(s,t)\mid \ s=s_0+k(b/d),t=t_0-k(a/d),k\in \mathbb{Z}\} {(s,t) s=s0+k(b/d),t=t0k(a/d),kZ}

其实就是左侧的 ( s , t ) (s,t) (s,t)在做调和 使得各自变化后 Δ ( a s + b t ) = 0 \Delta(as+bt)=0 Δ(as+bt)=0继续满足不定方程 这种调和肯定是周期性的 通过最小公倍数不难想到 对于 s s s周期就是 b / d b/d b/d t t t周期就是 a / d a/d a/d 同时一个 + k +k +k倍一个 − k -k k倍 正负性相反正好使得左侧代数式不变

假如我们还有一个不定方程

a s + b t = p as+bt=p as+bt=p

注意这里 p p p已经不是我们之前假设最小正整数的了 是单纯的变量

如果 d ∣ p d\mid p dp 那么记 p / d = v p/d=v\quad p/d=v ( s ′ , t ′ ) (s',t') (s,t)表示上文方程值为 d d d的一个解 我们有

a ( s ′ ⋅ v ) + b ( t ′ ⋅ v ) = d v = p a(s'\cdot v)+b(t'\cdot v)=dv=p a(sv)+b(tv)=dv=p

套用等号右侧为 d d d的不定方程的解 ( s 0 , t 0 ) (s_0,t_0) (s0,t0) 有该新不定方程解集为

{ ( s , t ) ∣   s = ( s 0 ⋅ v ) + k ( b / d ) , t = ( t 0 ⋅ v ) − k ( a / d ) , k ∈ Z } \{(s,t)\mid \ s=(s_0\cdot v)+k(b/d),t=(t_0\cdot v)-k(a/d),k\in \mathbb{Z}\} {(s,t) s=(s0v)+k(b/d),t=(t0v)k(a/d),kZ}

确实是如出一辙的

以上就是贝祖定理为我们呈现的不定方程解集

当然 我们之前的假设是 d ∣ p d\mid p dp 现在若 d ∤ p d\nmid p dp 会发生什么呢?

直觉告诉我们这个 p p p大概无解

其实很好证明

因为 d = g c d ( a , b ) 则对于整数数对 ( s , t ) 一定有 d ∣ ( a s + b t ) 反证 : 假设存在 a s + b t = p 那么 d ∣ p 与条件 d ∤ p 相悖 所以无解 \begin{align} &因为d=gcd(a,b) \\ &则对于整数数对(s,t)一定有\\ &d\mid (as+bt)\\ &反证:假设存在\\ &as+bt=p\\ &那么d\mid p \\ &与条件d\nmid p相悖 \\ &所以无解 \end{align} 因为d=gcd(a,b)则对于整数数对(s,t)一定有d(as+bt)反证:假设存在as+bt=p那么dp与条件dp相悖所以无解

所以贝祖定理又变相给出了整数数对解存在性的解释

所以 d ∣ p d\mid p dp时不定方程的解集为可数集 与原方程完全等势 而 d ∤ p d\nmid p dp时解集 = ∅ =\emptyset =

推广到多元一次

再看一个更特别的例子 假如不定方程系数不只是 a , b a,b a,b —— 我的意思是给定整数系数序列 A A A 那么关于多元一次不定方程

A 1 S 1 + A 2 S 2 + . . . + A n S n = p A_1S_1+A_2S_2+...+A_nS_n=p A1S1+A2S2+...+AnSn=p

的解即序列 S S S会是什么呢

再令 p p p为最小整数解 d d d g c d ( A 1 , A 2 , . . . , A n ) gcd(A_1,A_2,...,A_n) gcd(A1,A2,...,An)

如果我们用一般贝祖定理的证明方法 会有

p ∣ A 1   ,   p ∣ A 2   ,   . . .   ,   p ∣ A n p\mid A_1\ ,\ p\mid A_2 \ ,\ ...\ ,\ p\mid A_n pA1 , pA2 , ... , pAn

自然又有了 p ∣ d   ,   d ∣ p 也就是 d = p 自然又有了p\mid d \ , \ d\mid p \quad 也就是d=p 自然又有了pd , dp也就是d=p

本质上这多元一次和二元一次是一样的

对于它的上述具体证明和解存在性判断我留给你来做 我相信这并不难 如果你能完成那说明你学的很扎实 真是棒极了

关于整个多元一次不定方程的解集表示比较复杂 化用费马在《算术》一书中的一句话:“我有一个绝妙的推导方法(指的费马大定理),可惜这里空白太小,写不下。” 详情请参附录 A .2 A.2 A.2

我还希望你能一同完成本节开头的那几个例子 他们会是很好的练习(不过到目前我们只能判断是否有解 把解集真正意义地弄出来需要用下一节的拓展欧几里得先得出一个特殊解 ( s 0 , t 0 ) (s_0,t_0) (s0,t0))

拓展欧几里得の实现

上一节我们看了贝祖定理 现在终于又回到 O I OI OI了(事实上这也是数学手推不定方程解的好方法 只是我们利用计算机帮我们迭代递推了)

以下部分拓展欧几里得会以 e x g c d exgcd exgcd的形式表示

拓展欧几里得其实是对二元一次不定方程

a s + b t = d as+bt=d as+bt=d

求一个特殊解 这有四点要解释

(1) 我们讨论方程右边恰为 d = g c d ( a , b ) d=gcd(a,b) d=gcd(a,b) 因为上一节我们讨论了其他情况的解集都是基于该特殊式的解集

(2) 我们只需要求一个特殊解 因为上一节我们也讨论了解集的其他解只是其中一个解的衍生 (这也是我在上一节直接说"如果存在一个解"的原因 因为找这一个解的问题正是在这里解决的 是不是有前后呼应那味道了[doge])

(3)拓展欧几里得之所以又叫拓展 其实就是在原先辗转相除法的过程中一边求 g c d ( a , b ) gcd(a,b) gcd(a,b)一边求出特殊解 ( s 0 , t 0 ) (s_0,t_0) (s0,t0) 两者的方法都是同时迭代进行的 所以确实是欧几里得的拓展 (迭代方式我们会在下文看见)

(4)拓展欧几里得并不是在可数集随便扔一个解给我们 它给出的特殊解自有特殊性 我们会在下文说到

梳理好了之后我们要把一般辗转相除法的过程正经列出来(而不是之前的自然语言解释 虽然我觉得自然语言解释会充分通俗易懂 不过数理的形式整洁之美也是我们在追求的)

我们令每次相除的商为 q q q 余数为 r r r 特别地记 r 0 = a , r 1 = b r_0=a,r_1=b r0=a,r1=b 辗转相除法的过程应该是这样的 (接下来我们完全默认 a > b a>b a>b了)

r 0 = a , r 1 = b r 0 = r 1 q 1 + r 2 ( 在这里迭代 a , b ) r 1 = r 2 q 2 + r 3 . . . r i = r i + 1 q i + 1 + r i + 2 ( 其实就是 r 的递推式 ) . . . r n − 1 = r n q n + r n + 1 r n + 1 = 0  结束迭代 返回 r n \begin{align} & r_0=a,r_1=b \\ & r_0=r_1q_1+r_2 \quad (在这里迭代a,b) \\ & r_1=r_2q_2+r_3 \\ & ... \\ & r_i=r_{i+1}q_{i+1}+r_{i+2} \quad (其实就是r的递推式) \\ & ... \\ & r_{n-1}=r_{n}q_{n}+r_{n+1} \\ & r_{n+1}=0 \ 结束迭代\ 返回r_n \end{align} r0=a,r1=br0=r1q1+r2(在这里迭代a,b)r1=r2q2+r3...ri=ri+1qi+1+ri+2(其实就是r的递推式)...rn1=rnqn+rn+1rn+1=0 结束迭代 返回rn

接下来我们需要用到这些 q q q了(之前我们是直接丢弃的)

我们构造一个 ( s , t ) (s,t) (s,t)的序列(中间的都是过程量 我们最后只要 ( s n , t n ) (s_n,t_n) (sn,tn)) 满足

a s i + b t i = r i as_i+bt_i=r_i asi+bti=ri

特别地 ( s 0 , t 0 ) = ( 1 , 0 ) ( s 1 , t 1 ) = ( 0 , 1 ) (s_0,t_0)=(1,0)\quad (s_1,t_1)=(0,1) (s0,t0)=(1,0)(s1,t1)=(0,1)

于是 a s n + b t n = r n = d as_n+bt_n=r_n=d asn+btn=rn=d

根据 r i = r i + 1 q i + 1 + r i + 2 r_i=r_{i+1}q_{i+1}+r_{i+2} ri=ri+1qi+1+ri+2等价于 r i = r i − 2 − r i − 1 q i − 1 r_i=r_{i-2}-r_{i-1}q_{i-1} ri=ri2ri1qi1

a s i + b t i = r i = r i − 2 − r i − 1 q i − 1 a s i + b t i = ( a s i − 2 − b t i − 2 ) − ( a s i − 1 + b t i − 1 ) q i − 1 { s i = s i − 2 − s i − 1 q i − 1 t i = t i − 2 − t i − 1 q i − 1 \begin{gather} as_i+bt_i=r_i=r_{i-2}-r_{i-1}q_{i-1} \\ as_i+bt_i=(as_{i-2}-bt_{i-2})-(as_{i-1}+bt_{i-1})q_{i-1} \\ \left\{ \begin{gather} s_i=s_{i-2}-s_{i-1}q_{i-1} \\ t_i=t_{i-2}-t_{i-1}q_{i-1} \\ \end{gather} \right. \end{gather} asi+bti=ri=ri2ri1qi1asi+bti=(asi2bti2)(asi1+bti1)qi1{si=si2si1qi1ti=ti2ti1qi1

于是我们就得到了 ( s i , t i ) (s_i,t_i) (si,ti)的递推式 我们写成代码的形式

struct Gcd {
	int s,t,d; 
};
inline Gcd exgcd(int a,int b)
{
	int f1=(a>0)?(1):(-1),
		f2=(b>0)?(1):(-1),
		f3=0;
	a=abs(a),b=abs(b);
	if (a<b) swap(a,b),swap(f1,f2),f3=1;
	int s1=1,s2=0,s3,t1=0,t2=1,t3;
	int r,q;
	while (b)
	{
		r=a%b,q=a/b;
		s3=s1-q*s2;
		t3=t1-q*t2;
		s1=s2,s2=s3;
		t1=t2,t2=t3;
		a=b,b=r;
	}
	int s=s1*f1,t=t1*f2;
	if (f3) swap(s,t);
	return (Gcd){s,t,a};
}

看一下迭代的过程 w h i l e 循环 while循环 while循环内 每次操作都是迭代进 变量 ( s 1 , t 1 ) 变量(s_1,t_1) 变量(s1,t1) 整体和一般欧几里得差不多

有两个注意的点

(1) 关于 变量 f 1 , f 2 变量f_1,f_2 变量f1,f2 我们之前说正负性对 g c d ( a , b ) gcd(a,b) gcd(a,b)无影响 可现在要取系数就要考虑正负性了 类比 a s = = ( − a ) ( − s ) as==(-a)(-s) as==(a)(s) 变量 f 1 , f 2 变量f_1,f_2 变量f1,f2打个标记 相对的对 s , t s,t s,t取反 ( 按需要乘 − 1 ) (按需要乘-1) (按需要乘1) 就完美了 举个例子

6 s − 4 t = 2 6s-4t=2 6s4t=2

函数返回前跑的解是 ( 1 , − 1 ) (1,-1) (1,1)这是相对于 6 s + ∣ − 4 ∣ t = 2 6s+|-4|t=2 6s+4∣t=2的解 通过标记对 t t t取反就变成 ( 1 , 1 ) (1,1) (1,1)

(2) 因为我们 g c d gcd gcd一直在默认一开始 a > b a>b a>b 所以我们要打一个标记 f 3 f3 f3 最后考虑 s , t s,t s,t分别是原来的哪个参数

现在你可以练习去手推不定方程了 并尝试找一找拓展欧几里得所给解有什么特殊性

拓展欧几里得再拓展

接下来让我们看两个拓展欧几里得的二级结论

拓展欧几里得解的特殊性

首先给出该特殊性 我们之前有表示出二元一次不定方程的解集

{ s , t ∣   s = s 0 + k ( b / d ) , t = t 0 − k ( a / d ) , k ∈ Z } \{s,t\mid \ s=s_0+k(b/d),t=t_0-k(a/d),k\in \mathbb{Z}\} {s,t s=s0+k(b/d),t=t0k(a/d),kZ}

对于该可数集 我们知道一定有 ( s ′ , t ′ ) (s',t') (s,t)它的 ∣ s ∣ + ∣ t ∣ |s|+|t| s+t是所有数对解中最小的(但不一定唯一 至多唯二) 而拓展欧几里得所给出的解刚好是这个最小值 (如果你想知道哪些解是这个最小值 你可以先利用exgcd算出 ( s 0 , t 0 ) (s_0,t_0) (s0,t0)以及最小值 检查k=1或-1(只可能是他们俩其一 参附录 A .3 A.3 A.3))

关于为什么exgcd收敛于最小值 你可以简单地想相除其实就是在做放缩 这个放缩恰好收敛了解(详情参附录 A .3 A.3 A.3)

不过该最小值性质要求一定是二元一次 多元后可能会有更小的值

多元的拓展欧几里得

再次面对已知的整数系数序列 A A A

A 1 S 1 + A 2 S 2 + . . . + A n S n = d = g c d ( A 1 , A 2 , . . . , A n ) A_1S_1+A_2S_2+...+A_nS_n=d=gcd(A_1,A_2,...,A_n) A1S1+A2S2+...+AnSn=d=gcd(A1,A2,...,An)

我们如何求解呢?其实很容易 就是嵌套的二元 e x g c d exgcd exgcd (类似于 g c d ( a , b , c ) gcd(a,b,c) gcd(a,b,c)的实质是 g c d ( g c d ( a , b ) , c ) gcd(gcd(a,b),c) gcd(gcd(a,b),c)的嵌套) 我们先拿三元举例

a s + b t + c w = d = g c d ( a , b , c ) as+bt+cw=d=gcd(a,b,c) as+bt+cw=d=gcd(a,b,c)

我们先考虑 s , t s,t s,t d 1 = g c d ( a , b ) d_1=gcd(a,b) d1=gcd(a,b) 对于

a s ′ + b t ′ = d 1 as'+bt'=d_1 as+bt=d1

e x g c d exgcd exgcd得出解 ( s 0 ′ , t 0 ′ ) (s'_0,t'_0) (s0,t0) 根据之前我们在贝祖讨论的 a ( s ′ v ) + b ( t ′ v ) = g c d ( a , b ) v = p a(s'v)+b(t'v)=gcd(a,b)v=p a(sv)+b(tv)=gcd(a,b)v=p 我们现在考虑这个二元一次不定方程

d 1 z + c w = d d_1z+cw=d d1z+cw=d

我们把他作为二元一次不定方程用exgcd得出解 ( z 0 , w 0 ) (z_0,w_0) (z0,w0) 利用 a ( s ′ v ) + b ( t ′ v ) = g c d ( a , b ) v = p a(s'v)+b(t'v)=gcd(a,b)v=p a(sv)+b(tv)=gcd(a,b)v=p我们有对于原三元一次不定方程的特解

( s 0 ′ z 0 , t 0 ′ z 0 , w 0 ) (s'_0z_0,t'_0z_0,w_0) (s0z0,t0z0,w0)

我们重新回到序列 A A A 为了便于得到通式我们在 A 1 A_1 A1前加入一个无影响的 A 0 = 0 A_0=0 A0=0 d i = g c d ( A 0 , A 1 , A 2 , . . . , A i + 1 ) d_i=gcd(A_0,A_1,A_2,...,A_{i+1}) di=gcd(A0,A1,A2,...,Ai+1)

上述嵌套可以理解为 做二元一次不定方程的系数数对为

( ( ( ( A 0 , A 1 ) , A 2 ) , . . . ) , A n ) ((((A_0,A_1),A_2),...),A_n) ((((A0,A1),A2),...),An)

那么
A 0 s 1 + A 1 s 2 = d 0 A 0 有一个嵌套内的解 s 1   ,   A 1 有一个嵌套内的解 s 2 ( A 0 , A 1 ) 整体作为一项也就是 d 0 与 A 2 放在一个二元一次不定方程里 d 0 s 3 + A 2 s 4 = d 1 d 1 有一个嵌套内的解 s 3 A 2 有一个嵌套内的解 s 4 . . . 如此嵌套计算 \begin{gather} A_0s_1+A_1s_2=d_0\\ A_0有一个嵌套内的解s_1\ ,\ A_1有一个嵌套内的解s_2\\ (A_0,A_1)整体作为一项也就是d_0 \\ 与A_2放在一个二元一次不定方程里\\ d_0s_3+A_2s_4=d_1\\ d_1有一个嵌套内的解s_3\\ A_2有一个嵌套内的解s_4\\ ...如此嵌套计算\\ \end{gather} A0s1+A1s2=d0A0有一个嵌套内的解s1 , A1有一个嵌套内的解s2(A0,A1)整体作为一项也就是d0A2放在一个二元一次不定方程里d0s3+A2s4=d1d1有一个嵌套内的解s3A2有一个嵌套内的解s4...如此嵌套计算

那么我们其实一直在做一个二元一次不定方程

d i − 1 s 2 i + 1 + A i + 1 s 2 i + 2 = d i ( 1 ≤ i ≤ n − 1 ) d_{i-1}s_{2i+1}+A_{i+1}s_{2i+2}=d_{i}\quad (1\leq i\leq n-1) di1s2i+1+Ai+1s2i+2=di(1in1)

特别地记 s 1 无意义 ( 其实应该 ∈ R ) s 2 = 1 s_1无意义(其实应该\in \mathbb{R})\quad s_2=1 s1无意义(其实应该R)s2=1

则有一个特解序列 { S ∣   S i = s 2 i ⋅ ∏ j = i n − 1 s 2 j + 1   ,   1 ≤ i ≤ n } \{S\mid \ S_i=s_{2i}\cdot \prod_{j=i}^{n-1}s_{2j+1}\ ,\ 1\leq i \leq n\} {S Si=s2ij=in1s2j+1 , 1in}

把它带入多元一次不定方程的通式得到整个解集 请参附录 A .2 A.2 A.2

拓展欧几里得:乘法逆元

如果你看到这了 那么你已经成功 95 % 95\% 95%了 因为这节非常简单 而且很多东西再一次只是用到贝祖定理得出的 我们马上就能完成第一种对乘法逆元求解的方法的学习

e x g c d exgcd exgcd-乘法逆元 理论

补充: 模 b b b的完全剩余系其实就是集合{0,1,2,…,b-1} 因为整数集模完后只会剩下这些值 如果你说负数怎么取余呢 其实取余的标准定义为

a   m o d   m = r 其中  a = k m + r ( 0 ≤ r < m   ,   k ∈ Z ) \begin{gather} a\ mod\ m=r\\ 其中\ a=km+r \quad (0\leq r<m\ ,\ k\in \mathbb{Z}) \end{gather} a mod m=r其中 a=km+r(0r<m , kZ)

那么类似 − 17   m o d   5 -17\ mod\ 5 17 mod 5 应该是 3 3 3 因为 − 17 = ( − 4 ) ∗ 5 + 3 -17=(-4)*5+3 17=(4)5+3

现在我们来考虑同余

a s ≡ 1 ( m o d   b ) as \equiv 1 \quad (mod\ b) as1(mod b)

等价于存在整数 t t t使得

a s + b t = 1 as+bt=1 as+bt=1

首先我们根据乘法逆元的定义知道 a , s a,s a,s互为 m o d   b mod\ b mod b下的乘法逆元 而它 等价于第二个二元一次不定方程

我们已经在拓展贝祖定理一节讨论过 这个二元一次不定方程有解时需要

(   g c d ( a , b ) = d   ) ∣ 1 (\ gcd(a,b)=d\ )\mid 1 ( gcd(a,b)=d )1

又因为 d ≥ 1 d\geq 1 d1 事实上也就是 g c d ( a , b ) = 1 即 a , b 互质 gcd(a,b)=1即a,b互质 gcd(a,b)=1a,b互质

所以贝组定理给出了乘法逆元存在性的解释

在 m o d   m 下对于整数 a 当且仅当 g c d ( a , m ) = 1 时 a 存在乘法逆元 \begin{gather} 在mod\ m下对于整数a当且仅当gcd(a,m)=1时 \\ a存在乘法逆元 \end{gather} mod m下对于整数a当且仅当gcd(a,m)=1a存在乘法逆元

求解这个乘法逆元也很简单 通过 e x g c d exgcd exgcd求得一个 s 0 s_0 s0就好了(当然我们不需要 t 0 t_0 t0 可以把它扔掉)

事实上你直接套用函数给出的 s 0 s_0 s0可能小于0什么的 你需要再对 s 0 s_0 s0取关于 b b b的正模数 (至于为什么是直接取模下面解集给出解释) (以下默认 s 0 s_0 s0就是一个剩余系内的解)

我们还知道(还是在贝祖一节讨论完的解的表示) 这个不定方程的解集表示为(把 d = 1 d=1 d=1的特殊情况带代入)

{ ( s , t ) ∣   s = s 0 + k b   ,   t = t 0 − k a   ,   k ∈ Z } \{(s,t)\mid \ s=s_0+kb\ ,\ t=t_0-ka\ ,\ k\in \mathbb{Z}\} {(s,t) s=s0+kb , t=t0ka , kZ}

(如果 s 0 s_0 s0在模 b b b剩余系内 那么) 事实上在 m o d   b mod\ b mod b下只要上式 k ≠ 0 k\neq 0 k=0 于是 s 0 + k b  一定不在 m o d   b 的完全剩余系内 ( 向前 / 向后平移 b 肯定超出剩余系了这点应该显然吧 ) s_0+kb\ 一定不在mod\ b的完全剩余系内(向前/向后平移b肯定超出剩余系了 这点应该显然吧) s0+kb 一定不在mod b的完全剩余系内(向前/向后平移b肯定超出剩余系了这点应该显然吧) 也就是说 a a a有且只有一个逆元 于是我们用贝祖定理又得出了 乘法逆元唯一性的解释

(如果 s 0 s_0 s0并不在剩余系内 我们要使它 + k b +kb +kb以至于回到剩余系内 其实就是取模 b b b了)

总结就是

根据贝祖定理 在 m o d   m 剩余系下当且仅当 g c d ( a , m ) = 1 即 a , m 互质时 a 存在一个且仅有一个对应的乘法逆元 \begin{gather} 根据贝祖定理\\ 在mod\ m剩余系下当且仅当gcd(a,m)=1即a,m互质时\\ a存在一个且仅有一个对应的乘法逆元 \end{gather} 根据贝祖定理mod m剩余系下当且仅当gcd(a,m)=1a,m互质时a存在一个且仅有一个对应的乘法逆元

e x g c d exgcd exgcd-乘法逆元 实现

我们还是求解

a s ≡ 1 ( m o d   b ) as \equiv 1 \quad (mod\ b) as1(mod b)

先转化成

a s + b t = 1 as+bt=1 as+bt=1

套用 e x g c d ( a , b ) exgcd(a,b) exgcd(a,b)求得 ( s 0 , t 0 )   ,   d (s_0,t_0)\ ,\ d (s0,t0) , d

如果 d ≠ 1 d\neq 1 d=1 说明 a a a并不存在关于 m o d   b mod\ b mod b的逆元 (多数时候题目是保证存在的 不需要这一步)

否则 d = 1 d=1 d=1 那么我们还需要对 s 0 s_0 s0关于 b b b求一次正模数 以保证 s 0 s_0 s0确实是模 b b b剩余系内的一个元素

Tip: 我们一直在强调取正模数 是因为编码内计算机对负数取模只会取得负模数 所以这一步需要我们额外手写一个计算函数 举个例子

求 m o d   7  下 3 的乘法逆元 套用 e x g c d 我们得到的解 ( − 2 , 1 ) 很显然 − 2 并不在模 7 的完全剩余系内 这时候我们需要取模 可是让计算机取模的话 : − 2   m o d   7 = − 2  看起来在白费功夫 其实计算机最后只会算到负数 就像计算机会这么计算 : − 17   m o d   5 = − 2  因为 − 17 = ( − 3 ) ∗ 5 − 2 0 ≤ ∣ − 2 ∣ < 5  导致计算机认为这个计算任务完成了 这对于数学上的取余是不合法的 所以我们要手动取正模 − 2   m o d   7 = 5 3 ∗ 5 = 15 ≡ 1 ( m o d   7 ) 检验完是无误的 \begin{gather} 求mod\ 7\ 下3的乘法逆元\\ 套用exgcd我们得到的解(-2,1)\\ 很显然-2并不在模7的完全剩余系内\\ 这时候我们需要取模\ 可是让计算机取模的话:\\ -2\ mod\ 7=-2\ 看起来在白费功夫\\ 其实计算机最后只会算到负数\ 就像计算机会这么计算:\\ -17\ mod\ 5=-2\ 因为-17=(-3)*5-2 \\ 0\leq |-2|<5\ 导致计算机认为这个计算任务完成了\\ 这对于数学上的取余是不合法的\ 所以我们要手动取正模\\ -2\ mod\ 7=5\\ 3*5=15\equiv1 \quad (mod\ 7)\\ 检验完是无误的\\ \end{gather} mod 7 3的乘法逆元套用exgcd我们得到的解(2,1)很显然2并不在模7的完全剩余系内这时候我们需要取模 可是让计算机取模的话:2 mod 7=2 看起来在白费功夫其实计算机最后只会算到负数 就像计算机会这么计算:17 mod 5=2 因为17=(3)5202∣<5 导致计算机认为这个计算任务完成了这对于数学上的取余是不合法的 所以我们要手动取正模2 mod 7=535=151(mod 7)检验完是无误的

至于手写取正模数函数 可以这么写

inline int Mod(int a,int mod){
	return ((a%mod)+mod)%mod;
}

传入的 a a a不论是否为负最后取余结果都会在剩余系内(合法)

附上整体的模板

#include<bits/stdc++.h>
typedef long long ll;
using namespace std;
const ll maxn=1e6+10;
inline ll read(){
	ll ret=0,f=1;char ch=getchar();
	while (ch<'0' || ch>'9') {if(ch=='-')f=-1;ch=getchar();}
	while (ch>='0'&&ch<='9') ret=ret*10+ch-'0',ch=getchar();
	return ret*f;
}

struct Gcd {
	int s,t,d; 
};
inline Gcd exgcd(int a,int b)
{
	int f1=(a>0)?(1):(-1),
		f2=(b>0)?(1):(-1),
		f3=0;
	a=abs(a),b=abs(b);
	if (a<b) swap(a,b),swap(f1,f2),f3=1;
	int s1=1,s2=0,s3,t1=0,t2=1,t3;
	int r,q;
	while (b)
	{
		r=a%b,q=a/b;
		s3=s1-q*s2;
		t3=t1-q*t2;
		s1=s2,s2=s3;
		t1=t2,t2=t3;
		a=b,b=r;
	}
	int s=s1*f1,t=t1*f2;
	if (f3) swap(s,t);
	return (Gcd){s,t,a};
}
inline int Mod(int a,int mod){
	return (a%mod+mod)%mod;
}
int main()
{
	int a=read(),b=read();
	Gcd g=exgcd(a,b);
	int s=g.s,t=g.t,d=g.d;
	int inv=Mod(s,b);
	if (d!=1) printf("-1");
	else printf("%d",inv);
}

至此我们就完成了一版求解乘法逆元的学习 真是可喜可贺不是么

附录

附录 0 0 0

这篇附录是后续补上的 所以起名为0

这篇附录里我们会看到很多 非常显然(但又需要严谨证明) 的结论

事实上在系统教材的学习中 应该先是贝祖定理再是接下来依次几节 我建议你先看完正文贝祖定理一节再来到这里

# 0.1 \# 0.1 #0.1 欧几里得引理

这个引理的表述是:

( 1 ) 一般地 若 g c d ( a , b ) = 1  且  a ∣ ( b ⋅ k ) 那么 a ∣ k ( 2 ) 特别地 若素数 p 满足  p ∣ ( m ⋅ n ) 则  p ∣ m   ,   p ∣ n  至少满足其一 \begin{gather} (1)一般地\ 若gcd(a,b)=1\ 且\ a\mid (b\cdot k) \\ 那么a\mid k \\ (2)特别地\ 若素数p满足\ p\mid (m\cdot n) \\ 则\ p\mid m\ ,\ p\mid n\ 至少满足其一 \end{gather} (1)一般地 gcd(a,b)=1  a(bk)那么ak(2)特别地 若素数p满足 p(mn) pm , pn 至少满足其一

以下是证明

因为 g c d ( a , b ) = 1  并根据贝祖定理 存在整数 s , t 使得 a s + b t = 1 两边同乘 k  得到 a s k + b t k = k 又因为  a ∣ ( b k )  我们可以知道 a ∣ a s k   ,   a ∣ ( b k ⋅ t ) 所以 a ∣ ( a s k + b t k = k ) 得证 对于特别地情况 ( 1 )   p ∣ m  时符合结论 ( 2 )   p ∤ m  时根据素数和最大公约数的定义 ( 这是为了强调没有循环论证 ) g c d ( p , m ) = 1 所以 g c d ( p , m ) = 1 且 p ∣ m n 套用一般欧几里得引理 得到 p ∣ n \begin{gather} 因为gcd(a,b)=1\ 并根据贝祖定理\\ 存在整数s,t使得\\ as+bt=1\\ 两边同乘k\ 得到\\ ask+btk=k\\ 又因为\ a\mid (bk)\ 我们可以知道\\ a\mid ask\ ,\ a\mid (bk\cdot t)\\ 所以a\mid (ask+btk=k)\\ 得证\\ \\ 对于特别地情况\\ (1)\ p\mid m\ 时 符合结论\\ (2)\ p\nmid m\ 时 根据素数和最大公约数的定义\\ (这是为了强调没有循环论证)\\ gcd(p,m)=1\\ 所以gcd(p,m)=1且p\mid mn\\ 套用一般欧几里得引理\ 得到\\ p\mid n\\ \end{gather} 因为gcd(a,b)=1 并根据贝祖定理存在整数s,t使得as+bt=1两边同乘k 得到ask+btk=k又因为 a(bk) 我们可以知道aask , a(bkt)所以a(ask+btk=k)得证对于特别地情况(1) pm 时符合结论(2) pm 时根据素数和最大公约数的定义(这是为了强调没有循环论证)gcd(p,m)=1所以gcd(p,m)=1pmn套用一般欧几里得引理 得到pn

如果你还想问为什么素数 p p p不整除 m m m时 有 g c d ( p , m ) = 1 gcd(p,m)=1 gcd(p,m)=1的话 请看:

对于素数 p  根据素数定义其因数有且仅有 1   ,   p 当 g c d ( p , m ) = p 时 根据最大公因数定义 ( p = g c d ( p , m ) ) ∣ m 与条件不符 当 g c d ( p , m ) = 1 时符合题意 \begin{gather} 对于素数p\ 根据素数定义其因数有且仅有1\ ,\ p \\ 当gcd(p,m)=p 时\ 根据最大公因数定义\\ (p=gcd(p,m))\mid m\\ 与条件不符\\ 当gcd(p,m)=1时符合题意 \end{gather} 对于素数p 根据素数定义其因数有且仅有1 , pgcd(p,m)=p 根据最大公因数定义(p=gcd(p,m))m与条件不符gcd(p,m)=1时符合题意

这里还有一个欧几里得引理推广

对于素数 p  如果 p ∣ ( a 1 a 2 . . . a n ) 那么对于其中至少一个 a i  有 p ∣ a i 证明也很简单和上文一致 我们把 ( a 1 a 2 . . . a n ) 看做 a i ⋅ m 这时回到一般欧几里得引理了 现在我交给你作为练习证明 我相信你能出色地完成它 \begin{gather} 对于素数p\ 如果p\mid (a_1a_2...a_n)\\ 那么对于其中至少一个a_i\ 有p\mid a_i\\ \\ 证明也很简单 和上文一致\\ 我们把(a_1a_2...a_n)看做a_i\cdot m\\ 这时回到一般欧几里得引理了\\ 现在我交给你作为练习证明\\ 我相信你能出色地完成它\\ \end{gather} 对于素数p 如果p(a1a2...an)那么对于其中至少一个ai pai证明也很简单和上文一致我们把(a1a2...an)看做aim这时回到一般欧几里得引理了现在我交给你作为练习证明我相信你能出色地完成它

# 0.2 \# 0.2 #0.2 唯一分解定理

唯一分解定理是非常显然的 哪怕是刚学完小学内容的人也会自己得出这样的结论:

对于整数 a 可以写为一种且仅有一种素数乘积的形式 形式地 用序列 p i 表示素数 用序列 k i 表示对应素数个数 有 a = p 1 k 1 ⋅ p 2 k 2 ⋅   . . .   ⋅ p n k n 且对于整数 a 仅有这一种表示形式 举个例子 对于 12  有 12 = 2 2 ∗   3 当然 12 不能写成其他素数相乘的形式了 \begin{gather} 对于整数a可以写为一种且仅有一种素数乘积的形式\\ 形式地\ 用序列p_i表示素数\ 用序列k_i表示对应素数个数\ 有\\ a=p_1^{k_1}\cdot p_2^{k_2}\cdot \ ...\ \cdot p_n^{k_n}\\ 且对于整数a仅有这一种表示形式\\ \\ 举个例子\ 对于12\ 有\\ 12=2^2*\ 3\\ 当然12不能写成其他素数相乘的形式了 \end{gather} 对于整数a可以写为一种且仅有一种素数乘积的形式形式地 用序列pi表示素数 用序列ki表示对应素数个数 a=p1k1p2k2 ... pnkn且对于整数a仅有这一种表示形式举个例子 对于12 12=22 3当然12不能写成其他素数相乘的形式了

这个定理就被称为唯一分解定理 根据上述表述 它具有 (1)存在性 (2)唯一性

没错 它被称为定理说明它并不是自然公理 如果在初学数论时你直接用该定理去理解其他结论是很不明智的 (因为你很可能在循环论证 就像附录0.1的欧几里得引理并不是该定理证明的 甚至我们是用欧几里得引理来证明唯一分解定理 我们也是先证明贝祖定理再证明该定理)

用一种不太好的说法 循环论证就是本该是爸爸证儿子的事情却造成了儿子证爸爸 如果你在平时的思考中不注意这一点你将非常危险

对于存在性我们用数学归纳法证明

给出命题 : 任意大于 1 的整数可以写作素数乘积的形式 对于全体素数这点肯定是符合的 基例有 2 , 3 , 5 , 7... 进一步归纳假设为大于 1 小于 n 的整数可以写作素数乘积的形式 而对于合数 n 肯定能写作 n = a b   ( 1 < a , b < n )   ( 合数的定义 ) a , b 在归纳之内于是 n 也能写作素数乘积 ( 把 a , b 写成素数乘积展开 ) 的形式 ( 例如 4 = 2 ∗ 2   ,   6 = 2 ∗ 3   ,   8 = 2 ∗ 4 = 2 ∗ ( 2 ∗ 2 )   . . . ) 因为原始基例 ( 2 , 3 , 5... ) 是符合这个归纳的 \begin{gather} 给出命题:任意大于1的整数可以写作素数乘积的形式\\ 对于全体素数这点肯定是符合的\\ 基例有2,3,5,7...\\ 进一步归纳假设为大于1小于n的整数可以写作素数乘积的形式\\ 而对于合数n 肯定能写作n=ab \ (1<a,b<n)\ (合数的定义)\\ a,b在归纳之内于是n也能写作素数乘积(把a,b写成素数乘积展开)的形式\\ (例如4=2*2\ ,\ 6=2*3\ ,\ 8=2*4=2*(2*2)\ ...)\\ 因为原始基例(2,3,5...)是符合这个归纳的\\ \end{gather} 给出命题:任意大于1的整数可以写作素数乘积的形式对于全体素数这点肯定是符合的基例有2,3,5,7...进一步归纳假设为大于1小于n的整数可以写作素数乘积的形式而对于合数n肯定能写作n=ab (1<a,b<n) (合数的定义)a,b在归纳之内于是n也能写作素数乘积(a,b写成素数乘积展开)的形式(例如4=22 , 6=23 , 8=24=2(22) ...)因为原始基例(2,3,5...)是符合这个归纳的

唯一性用反证法

我们先造元素都是素数的序列 p , q 反证 : 存在某个大于 1 的整数 n 真的可以写为 p 1 p 2 . . . p s 和 q 1 q 2 . . . q t 两种形式 对于素数 p 1 有 p 1 ∣ ( n = q 1 q 2 . . q t ) 根据欧几里得引理推广 ( 附录 0.1 )  我们知道 对于 p 1 一定存在至少一个 q i 使得 p 1 ∣ q i 根据素数的定义一定有  p 1 = q i 我们对 q 序列排序正好使 p 1 = q 1 那么 p 1 p 2 . . p s = q 1 q 2 . . . q t 同除以 p 1 = q 1  得到 p 2 p 3 . . . p s = q 2 q 3 . . . q t 那么我们可以继续按上述操作新的等式 一旦 s ≠ t   ( 假设是 s < t )  最后会有 1 = q s + 1 q s + 2 . . . q t 显然是不合法的 ( 素数肯定大于 1 ) 那么 s = t 并且还说明此前 p , q 序列内元素一一对应 这与反证假设相悖 得证整数 n 只能写作唯一一种素数乘积形式 \begin{gather} 我们先造元素都是素数的序列p,q\\ 反证:存在某个大于1的整数n真的可以写为p_1p_2...p_s和q_1q_2...q_t两种形式\\ 对于素数p_1有p_1\mid (n=q_1q_2..q_t)\\ 根据欧几里得引理推广(附录0.1)\ 我们知道\\ 对于p_1一定存在至少一个q_i使得p_1\mid q_i\\ 根据素数的定义一定有\ p_1=q_i\\ 我们对q序列排序 正好使p_1=q_1\\ 那么p_1p_2..p_s=q_1q_2...q_t\\ 同除以p_1=q_1\ 得到\\ p_2p_3...p_s=q_2q_3...q_t\\ 那么我们可以继续按上述操作新的等式\\ 一旦s\neq t\ (假设是s<t)\ 最后会有\\ 1=q_{s+1}q_{s+2}...q_t\\ 显然是不合法的(素数肯定大于1)\\ 那么s=t\quad 并且还说明此前p,q序列内元素一一对应\\ 这与反证假设相悖\\ 得证整数n只能写作唯一一种素数乘积形式\\ \end{gather} 我们先造元素都是素数的序列p,q反证:存在某个大于1的整数n真的可以写为p1p2...psq1q2...qt两种形式对于素数p1p1(n=q1q2..qt)根据欧几里得引理推广(附录0.1) 我们知道对于p1一定存在至少一个qi使得p1qi根据素数的定义一定有 p1=qi我们对q序列排序正好使p1=q1那么p1p2..ps=q1q2...qt同除以p1=q1 得到p2p3...ps=q2q3...qt那么我们可以继续按上述操作新的等式一旦s=t (假设是s<t) 最后会有1=qs+1qs+2...qt显然是不合法的(素数肯定大于1)那么s=t并且还说明此前p,q序列内元素一一对应这与反证假设相悖得证整数n只能写作唯一一种素数乘积形式

# 0.3 \# 0.3 #0.3 同余の消去律

同余的消去律也称为同余的除法规则 它的表述如下:

若  a c ≡ b c ( m o d   m ) 则  a ≡ b ( m o d   m g c d ( m , c ) ) 特别地当 g c d ( m , c ) = 1 即 m , c 互质时 特化为 a ≡ b ( m o d   m ) \begin{gather} 若\ ac\equiv bc\quad (mod\ m)\\ 则\ a\equiv b\quad (mod\ \frac{m}{gcd(m,c)})\\ 特别地 当gcd(m,c)=1即m,c互质时\ 特化为\\ a\equiv b\quad (mod\ m) \end{gather}  acbc(mod m) ab(mod gcd(m,c)m)特别地当gcd(m,c)=1m,c互质时 特化为ab(mod m)

这是一个非常敏感的话题 因为它向我们阐述了同余系统下真正的除法规则 它只是有条件所以不适用于日常的除法 但仍遵循一套理论的

但是大多数时候你不好使用这套法则 所以你还是需要借用逆元的方法变相做除

接下来我们证明该法则

已知  a c ≡ b c ( m o d   m ) 等价于  ( a − b ) c ≡ 0 ( m o d   m ) 所以  m ∣ ( ( a − b ) c ) 我们记 d = g c d ( m , c )  且  m = d ⋅ m ′   ,   c = d ⋅ c ′ 代入上式得  d m ′ ∣ d c ′ ( a − b ) 即  m ′ ∣ c ′ ( a − b ) 根据欧几里得引理 ( 附录 0.1 )  由于 g c d ( m ′ , c ′ ) = 1 我们有 m ′ ∣ ( a − b ) 写成同余的形式  a ≡ b ( m o d   m ′ ) 即  a ≡ b ( m o d   m g c d ( m , c ) ) 得证 \begin{gather} 已知\ ac\equiv bc\quad (mod\ m)\\ 等价于\ (a-b)c\equiv 0\quad(mod\ m)\\ 所以\ m\mid ((a-b)c)\\ 我们记d=gcd(m,c)\ 且\ m=d\cdot m'\ ,\ c=d\cdot c'\\ 代入上式得\ dm'\mid dc'(a-b)\\ 即\ m'\mid c'(a-b)\\ 根据欧几里得引理(附录0.1)\ 由于gcd(m',c')=1\\ 我们有 m'\mid (a-b)\\ 写成同余的形式\ a\equiv b\quad (mod\ m') 即\ a\equiv b\quad (mod\ \frac{m}{gcd(m,c)})\\ 得证\\ \end{gather} 已知 acbc(mod m)等价于 (ab)c0(mod m)所以 m((ab)c)我们记d=gcd(m,c)  m=dm , c=dc代入上式得 dmdc(ab) mc(ab)根据欧几里得引理(附录0.1) 由于gcd(m,c)=1我们有m(ab)写成同余的形式 ab(mod m) ab(mod gcd(m,c)m)得证

关于消去律的使用举个例子(大多时候是数论的证明使用 说明与模数互质的因数可以消去)

求 x 的同余 3 x ≡ 2 ( m o d   5 ) 虽然 g c d ( 3 , 5 ) = 1  就算你同除以三也没什么用 难道你要说 x ≡ 2 3 吗 正确的做法起码是观察到上式等价于 3 x ≡ 12 ( m o d   5 ) 同除以 3 得到 x ≡ 4 ( m o d   5 ) 另一种方法就是先求得 3 关于 m o d   5 的逆元是 2 有  3 x ∗ 2 ≡ 2 ∗ 2 ( m o d   5 ) 同样是  x ≡ 4 \begin{gather} 求x的同余\\ 3x\equiv 2\quad (mod\ 5)\\ 虽然gcd(3,5)=1\ 就算你同除以三也没什么用\ 难道你要说x\equiv \frac{2}{3}吗\\ 正确的做法起码是观察到上式等价于\\ 3x\equiv 12\quad (mod\ 5)\\ 同除以3得到\\ x\equiv 4\quad (mod\ 5)\\ 另一种方法就是先求得3关于mod\ 5的逆元是2\\ 有\ 3x*2\equiv 2*2 (mod\ 5)\\ 同样是\ x\equiv 4 \end{gather} x的同余3x2(mod 5)虽然gcd(3,5)=1 就算你同除以三也没什么用 难道你要说x32正确的做法起码是观察到上式等价于3x12(mod 5)同除以3得到x4(mod 5)另一种方法就是先求得3关于mod 5的逆元是2 3x222(mod 5)同样是 x4

附录 A A A

A .1 A.1 A.1 辗转相除法算法の复杂度

其实证明很简单 对于 a > b a>b a>b g c d ( a , b ) gcd(a,b) gcd(a,b) 我们讨论两种情况:

(1) a 2 ≥ b \frac{a}{2}\geq b 2ab r = a   m o d   b < a 2 r=a\ mod\ b<\frac{a}{2} r=a mod b<2a 所以我们O(1)就将余数变为原来一半

(2) a 2 < b \frac{a}{2}<b 2a<b 则第一步 a = b + r   ,   r = a − b < a 2 a=b+r\ ,\ r=a-b<\frac{a}{2} a=b+r , r=ab<2a 第二步求 g c d ( a − b , b )   ,   r ′ = b   m o d   ( a − b ) < a − b < a 2 gcd(a-b,b)\ ,\ r'=b\ mod\ (a-b)<a-b<\frac{a}{2} gcd(ab,b) , r=b mod (ab)<ab<2a O(2)就将余数变为原来的一半

综上复杂度最大为 O ( 2 l o g 2 n ) O(2log_2{n}) O(2log2n) 也就是 l o g log log级的

A .2 A.2 A.2 多元一次不定方程の解集

真是糟透了 我们不会向量 不会群论(如果你掌握他们 面对这个解集问题时答案一目了然对吧?)没法那么直接的使用这些知识表示(看出)解集 不过也有一些小白的做法(我当然没计划在这里讲向量和群论了)

首先我们要给出表示二元一次不定方程解集的严谨推导

我们有解 ( s 0 , t 0 ) 使得 a s 0 + b t 0 = d = gcd ⁡ ( a , b ) 对于通解 ( s , t ) 有 a ( s − s 0 ) + b ( t − t 0 ) = d − d = 0 也就是说 a Δ s + b Δ t = 0 这正是我在正文希望你能明白的 " ( s , t ) 其实在做调和 " 现在对它进行讨论 我们有 Δ s = − b a ⋅ Δ t ( 这个错误会在下面讨论 ) 其实理论上到这一步已经很不错了 由于没有约束 Δ t 有 Δ t ∈ Z 仔细一想我们刚刚直接将 b 除以 a 很显然得出的大概率不是一个整数 我们这样解决 令 a ′ = a / d ,   b ′ = b / d 会有 gcd ⁡ ( a ′ , b ′ ) = 1 也就是互质 则 Δ s = − b ′ a ′ Δ t ⇒ Δ t = a ′ b ′ Δ s 这下需要 a ′ ∣ Δ t 这样才能保证 Δ s 为整数 ! 直接记 t = a ′ k ,   k ∈ Z 则有 { Δ s = − b ′ k = − k ⋅ b d Δ t = a ′ k = k ⋅ a d k ∈ Z 现在和正文基本相同只不过 k 的正负性相反 ( 当然这没有影响 ) 因为 k ∈ Z 也有 − k ∈ Z 两种写法是等价的 所以我们有了解集 { ( s , t ) ∣ s = s 0 + k ( b / d ) ,   t = t 0 − k ( a / d ) ,   k ∈ Z } \begin{gather} 我们有解(s_0,t_0)使得\\ a s_0+b t_0=d=\gcd(a,b)\\ 对于通解(s,t)有\\ a(s-s_0)+b(t-t_0)=d-d=0\\ 也就是说a\Delta s+b\Delta t=0\\ 这正是我在正文希望你能明白的"(s,t)其实在做调和"\\ 现在对它进行讨论\\ 我们有\Delta s=-\frac{b}{a}\cdot\Delta t\quad(这个错误会在下面讨论)\\ 其实理论上到这一步已经很不错了\ 由于没有约束\Delta t有\\ \Delta t\in\mathbb{Z}\\ 仔细一想 我们刚刚直接将b除以a 很显然得出的大概率不是一个整数\\ 我们这样解决\ 令a'=a/d,\ b'=b/d\quad会有\gcd(a',b')=1也就是互质\\ 则\Delta s=-\frac{b'}{a'}\Delta t\quad\Rightarrow\quad \Delta t=\frac{a'}{b'}\Delta s\\ 这下需要a'\mid\Delta t 这样才能保证\Delta s为整数!\\ 直接记t=a'k,\ k\in\mathbb{Z}\\ 则有\left\{ \begin{gather} \Delta s=-b'k=-k\cdot\frac{b}{d}\\ \Delta t=a'k=k\cdot\frac{a}{d}\\ k\in\mathbb{Z}\\ \end{gather} \right.\\ 现在和正文基本相同 只不过k的正负性相反(当然这没有影响)\\ 因为k\in\mathbb{Z} 也有-k\in\mathbb{Z} 两种写法是等价的\\ 所以我们有了解集\\ \{(s,t)\mid s=s_0+k(b/d),\ t=t_0-k(a/d),\ k\in\mathbb{Z}\}\\ \end{gather} 我们有解(s0,t0)使得as0+bt0=d=gcd(a,b)对于通解(s,t)a(ss0)+b(tt0)=dd=0也就是说aΔs+bΔt=0这正是我在正文希望你能明白的"(s,t)其实在做调和"现在对它进行讨论我们有Δs=abΔt(这个错误会在下面讨论)其实理论上到这一步已经很不错了 由于没有约束ΔtΔtZ仔细一想我们刚刚直接将b除以a很显然得出的大概率不是一个整数我们这样解决 a=a/d, b=b/d会有gcd(a,b)=1也就是互质Δs=abΔtΔt=baΔs这下需要aΔt这样才能保证Δs为整数!直接记t=ak, kZ则有 Δs=bk=kdbΔt=ak=kdakZ现在和正文基本相同只不过k的正负性相反(当然这没有影响)因为kZ也有kZ两种写法是等价的所以我们有了解集{(s,t)s=s0+k(b/d), t=t0k(a/d), kZ}

好了 以二元一次为底层逻辑 接下来是多元一次不定方程的解集推导

我们有一个 S ′ 使得已知整数序列 A 1 S 1 ′ + A 2 S 2 ′ + ⋯ + A n S n ′ = d = gcd ⁡ ( A 1 , A 2 , … , A n ) 同样的通解满足 A 1 ( S 1 − S 1 ′ ) + A 2 ( S 2 − S 2 ′ ) + ⋯ + A n ( S n − S n ′ ) = 0 记 Δ i = S i − S i ′ 那么 A 1 Δ 1 + A 2 Δ 2 + ⋯ + A n Δ n = 0 现在我们要解出序列 { Δ i } 的通式 我们只有这一个方程代表一个约束 那么我们应该有 n − 1 个元素 Δ i 是自由的 ( 即取值是无约束的 ) 因为剩下一个元素 Δ i 是将其他 n − 1 个元素 Δ i 带入等式得到的 ( 非自然语言 ) 准确地说“自由的 n − 1 个元素 Δ i ” 应该叫自由参数或是阿贝尔群的秩 以上一大段话其实是想说 我们要钦定那些自由参数 计算最后一个被约束的元素 Δ i 开始使用我们的钦定大法 先钦定 { Δ 2 , … , Δ n } 我们有 A 1 Δ 1 = − A 2 Δ 2 − A 3 Δ 3 − ⋯ − A n Δ n 则 Δ 1 = − A 2 A 1 Δ 2 − A 3 A 1 Δ 3 − ⋯ − A n A 1 Δ n 同样类似二元一次证明里的那样 A i A 1 Δ i 不一定为整数 ( 我是指如果 Δ i 草率的取整数 ) 记 d i = gcd ⁡ ( A 1 , A i ) 我们化简 A i A 1 为 A i / d i A 1 / d i ( 以让上下互质 ) 那我们得到 ( A 1 / d i ) ∣ Δ 1 同样反向定义 ( i ≥ 2 ) Δ i = c i k i ( c i = A 1 / d i = A 1 / gcd ⁡ ( A 1 , A i )   ,   k i ∈ Z ) 那么 { Δ 1 = − ∑ i = 2 n   k i ( A i / d i ) Δ 2 = c 2 k 2 . . . Δ i = c i k i . . . Δ n = c n k n d i = g c d ( A 1 , A i ) c i = A 1 / d 1 k 2 , k 3 , . . . , k n ∈ Z 不容易啊我们终于有了 n 元一次不定方程的解集 { S ∣   S i = S i ′ + Δ i   , Δ 1 = − ∑ i = 2 n   k i ( A i / d i )   , Δ i = c i k i   ( i ≥ 2 )   , d i = g c d ( A 1 , A i )   , c i = A 1 / d i   ,   k i ∈ Z } \begin{gather} 我们有一个S'使得已知整数序列\\ A_1 S'_1+A_2 S'_2+\dots+A_n S'_n=d=\gcd(A_1,A_2,\dots,A_n)\\ 同样的通解满足A_1(S_1-S'_1)+A_2(S_2-S'_2)+\dots+A_n(S_n-S'_n)=0\\ 记\Delta_i=S_i-S'_i\\ 那么A_1 \Delta_1+A_2 \Delta_2+\dots+A_n \Delta_n=0\\ 现在我们要解出序列\{\Delta_i\}的通式\\ 我们只有这一个方程 代表一个约束\\ 那么我们应该有n-1个元素\Delta_i是自由的(即取值是无约束的)\\ 因为剩下一个元素\Delta_i是将其他n-1个元素\Delta_i带入等式得到的\\ (非自然语言)准确地说“自由的n-1个元素\Delta_i”\\ 应该叫自由参数或是阿贝尔群的秩\\ 以上一大段话其实是想说\\ 我们要钦定那些自由参数\ 计算最后一个被约束的元素\Delta_i\\ 开始使用我们的钦定大法\\ 先钦定\{\Delta_2,\dots,\Delta_n\}\\ 我们有A_1 \Delta_1=-A_2 \Delta_2-A_3 \Delta_3-\dots-A_n \Delta_n\\ 则\Delta_1=-\frac{A_2}{A_1}\Delta_2-\frac{A_3}{A_1}\Delta_3-\dots-\frac{A_n}{A_1}\Delta_n\\ 同样类似二元一次证明里的那样 \frac{A_i}{A_1}\Delta_i不一定为整数\\ (我是指如果\Delta_i草率的取整数)\\ 记d_i=\gcd(A_1,A_i)\\ 我们化简\frac{A_i}{A_1}为\frac{A_i/d_i}{A_1/d_i}(以让上下互质)\\ 那我们得到(A_1/d_i) \mid \Delta_1\\ 同样反向定义(i\geq2)\Delta_i=c_ik_i \quad (c_i=A_1/d_i=A_1/\gcd(A_1,A_i)\ ,\ k_i\in\mathbb{Z})\\ 那么\left\{ \begin{gather} \Delta_1=-\sum_{i=2}^n\ k_i(A_i/d_i)\\ \Delta_2=c_2k_2\\ ...\\ \Delta_i=c_ik_i\\ ...\\ \Delta_n=c_nk_n\\ d_i=gcd(A_1,A_i)\\ c_i=A_1/d_1\\ k_2,k_3,...,k_n\in \mathbb{Z} \end{gather} \right.\\ 不容易啊我们终于有了n元一次不定方程的解集\\ \{S|\ S_i=S'_i+\Delta_i\ ,\\ \Delta_1=-\sum_{i=2}^n\ k_i(A_i/d_i)\ ,\\ \Delta_i=c_ik_i\ (i\geq 2)\ ,\\ d_i=gcd(A_1,A_i)\ ,\\ c_i=A_1/d_i\ ,\ k_i\in\mathbb{Z}\} \end{gather} 我们有一个S使得已知整数序列A1S1+A2S2++AnSn=d=gcd(A1,A2,,An)同样的通解满足A1(S1S1)+A2(S2S2)++An(SnSn)=0Δi=SiSi那么A1Δ1+A2Δ2++AnΔn=0现在我们要解出序列{Δi}的通式我们只有这一个方程代表一个约束那么我们应该有n1个元素Δi是自由的(即取值是无约束的)因为剩下一个元素Δi是将其他n1个元素Δi带入等式得到的(非自然语言)准确地说自由的n1个元素Δi应该叫自由参数或是阿贝尔群的秩以上一大段话其实是想说我们要钦定那些自由参数 计算最后一个被约束的元素Δi开始使用我们的钦定大法先钦定{Δ2,,Δn}我们有A1Δ1=A2Δ2A3Δ3AnΔnΔ1=A1A2Δ2A1A3Δ3A1AnΔn同样类似二元一次证明里的那样A1AiΔi不一定为整数(我是指如果Δi草率的取整数)di=gcd(A1,Ai)我们化简A1AiA1/diAi/di(以让上下互质)那我们得到(A1/di)Δ1同样反向定义(i2)Δi=ciki(ci=A1/di=A1/gcd(A1,Ai) , kiZ)那么 Δ1=i=2n ki(Ai/di)Δ2=c2k2...Δi=ciki...Δn=cnkndi=gcd(A1,Ai)ci=A1/d1k2,k3,...,knZ不容易啊我们终于有了n元一次不定方程的解集{S Si=Si+Δi ,Δ1=i=2n ki(Ai/di) ,Δi=ciki (i2) ,di=gcd(A1,Ai) ,ci=A1/di , kiZ}

我真心怀疑我该不该在正文里说 “自己尝试推导多元一次不定方程的解集对你会是一个很好的练习”

该特解求解方法在多元拓展欧几里得

A .3 A.3 A.3 二元一次不定方程最优解

这里只用自然语言大概解释:

对于二元一次不定方程的解 ( s , t ) (s,t)\quad (s,t) ∣ s ∣ + ∣ t ∣ |s|+|t| s+t取最小值的我们称它最优解 把 ( s , t ) (s,t) (s,t)看做二维点对 根据解集的表示形式(只有一个线性变量k 严谨推导我们在附录 A .2 A.2 A.2中看到了) 点对应该在一个线性函数上 而绝对值之和 ∣ s ∣ + ∣ t ∣ |s|+|t| s+t应该在类似于 y = ∣ p k + q ∣ y=|pk+q| y=pk+q的绝对值函数上(参下图函数h) 那么整个函数成 “ V ” “V” V字型 由于点对并不连贯 在图像底端最靠近尖锐点的左右的两个解都有可能为最小值(事实上就和你二次函数同一个y可能对应两个x一样) (事实上这真的很不严谨 因为我们存在水杯型的情况 不过离散数学告诉我们水杯底长不超过1即也至多2个整点)有时候其一更偏下只有一个最优解 有时候两个值相等 就有两个最优解 (严谨证明还是在下文)

在这里插入图片描述

特别地 多元一次不定方程最小值不能被 e x g c d exgcd exgcd求出 不过 e x g c d exgcd exgcd给出的是最容易算出来的解 并接近于最小值(也就是实用+复杂度低 这被称为工程最优解)

关于为什么拓展欧几里得收敛且收敛于二元一次的最优解 (我已经不想写了…难道,你会想看吗) 收敛的感官体验你可以自己尝试

好吧我们用数学归纳法来严谨证明

首先对于复合函数 f ( k ) = ∣ k ( b / d ) + s 0 ∣ + ∣ − k ( a / d ) + t 0 ∣ f(k)=|k(b/d)+s_0|+|-k(a/d)+t_0| f(k)=k(b/d)+s0+k(a/d)+t0 最一般的情况就是上图了 甚至当两个子绝对值函数顶点相同这个复合函数 f ( k ) f(k) f(k)真的就是一个 V V V 了 当|b|=|a|时甚至还有如下这样的水杯型

在这里插入图片描述

请不要着急 以上所有函数都是我生造的一般的绝对值函数 其实和我们所探究的离散数学没什么关系(它们应该甚至不符合方程的解) 所以你似乎能看到水杯型底部有好多个整点(事实上用真正的二元一次不定式带入的系数一定会保证水杯底部至多2个整点 这是我们会在下面看到的) 不过这些都是假的 我只是带你感受一下这个复合函数

这里烂尾了 我实在写不下这个证明 原谅我在以后某次重置这一附录

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值