算法竞赛中的数学
算法竞赛中的数学
前言
文章介绍了笔者在算法竞赛数学专题集训中所学到的数学知识。文章共六章,其行文顺序秉持着从易到难的原则,部分文章内容参考了郑玄晔(玄燕)老师的 pdf 讲解,李煜东老师的《算法竞赛进阶指南》,洛谷学术组的《深入浅出程序算法竞赛(进阶篇)》,oi-wiki 等网站和文献资料,以及 ChatGPT-o4mini 的协助。
由于笔者数学能力极弱,文章中可能出现叙述不清的,不正确的情况,请谅解,并告知笔者修改,谢谢。
文章中以数学证明和公式推导为主,代码实现较少,仅在必要时给出 C++ 代码。
本文将在笔者的多个博客 (洛谷, 博客园, 知乎) 中发布。
第 0 章 基本定义
质数
若一个正整数无法被除了 \(1\) 和它本身以外的任何自然数整除,则该数被称为质数(或素数),否则该正整数被称为合数。
在自然数集中,质数分散较为稀疏。对于一个足够大的正整数 \(N\),小于等于 \(N\) 的质数约有 \(N \ln N\) 个。即平均每隔 \(\ln N\) 个数就会有一个质数。
约数
若整数 \(n\) 除以整数 \(d\) 的余数为 \(0\),即 \(d\) 能过整除 \(d\),则称 \(d\) 是 \(n\) 的约数(或因子),\(n\) 是 \(d\) 的倍数。
最大公约数
若一个自然数 \(n\) 同时是 \(a, b\) 的约数,则称该数为 \(a, b\) 的公约数。在所有 \(a, b\) 的公约数中最大的一个称为 \(a, b\) 的最大公约数,记作 \(\mathrm{gcd}(a, b)\)。
若一个自然数 \(n\) 同时是 \(a, b\) 的倍数,则称该数为 \(a, b\) 的公倍数。在所有 \(a, b\) 的公倍数中最小的一个称为 \(a, b\) 的最小公倍数,记作 \(\mathrm{lcm}(a, b)\)。
同理我们可以定义三个或多个数的最大公约数和最小公倍数。
互质
两个正整数 \(a\) 和 \(b\) 的最大公约数为 \(1\),即 \(\forall a,b \in \mathbb{N}\), 若 \(\mathrm{gcd}(a, b) = 1\),则称 \(a\) 和 \(b\) 互质。
同理我们可以定义三个或多个数互质。
同余
如果 \(a \mod m = b \mod m\),即他们除以 \(m\) 的余数相同,那么我们称 \(a\) 和 \(b\) 模 \(m\) 同余,记作 \(a \equiv b \pmod{m}\)
矩阵
在数学上,一个 \(n \times m\) 的矩阵(matrix)是一个有 \(n\) 行(row),\(m\)列(column)元素的矩形阵列。一个 \(n \times m\) 的矩阵如下所示:
\(A_{n \times m} = \begin{pmatrix} a_{11} & a_{12} & \cdots & a_{1m} \\ a_{21} & a_{22} & \cdots & a_{2m} \\ \vdots & \vdots & \ddots & \vdots \\ a_{n1} & a_{n2} & \cdots & a_{nm} \end{pmatrix}\)
对角线
对于方阵(即\(n \times n\) 的矩阵)我们定义该矩阵的主对角线为从左上角的元素到右下角的元素组成的集合。逆对角线即是从右上到左下组成的集合。
向量
一个 \(n \times 1\) 的矩阵被称为向量。我们把 \(n \times 1\) 的向量称作列向量,把 \(1 \times n\) 的向量称作行向量。一个\(n \times m\) 的矩阵也可看作是 \(m\) 个 \(n\)维向量。
空间
我们将全体 \(n\) 维向量组成的集合称作 \(n\) 维空间。
线性空间
数学上一个向量的集合 \(\mathrm V\) 是线性空间,当且仅当 \(\forall \vec{x},\vec{y} \in \mathrm{V}\) 都有
- \(\vec{x} + \vec{y} \in \mathrm{V}\)
- \(c\vec{x} \in \mathrm{V}\)
线性组合
对于 \(n\) 个向量 \(\vec{v_1}, \vec{v_2}, \vec{v_3}, \ldots, \vec{v_n}\), 它们的一组线性组合如下所示:
\(c_1\vec{v_1} + c_2\vec{v_2} + c_3\vec{v_3} + \ldots + c_n\vec{v_n}\)
其中 \(c_1, c_2, c_3, \ldots, c_n\) 是常数,我们成它们为该线性组合的系数。
在二维平面中线性组合表现为向量的伸缩与组合。
张出(span)
任取 \(n\) 个向量 \(\vec{v_1}, \vec{v_2}, \vec{v_3}, \ldots, \vec{v_n}\),若它们所有的线性组合构成空间 \(\mathrm{V}\),我们记 \(\mathrm{V} = \mathrm{span}(\vec{v_1}, \vec{v_2}, \vec{v_3}, \ldots, \vec{v_n})\) 为这 \(n\) 个向量张出的空间。
第 1 章 基础组合数学 & 简单数列
加法原理 & 乘法原理
加法原理:若事件 \(A\) 有两种解决方式,第一个方式有 \(a\) 种,第二个方式有 \(b\) 种,则事件 \(A\) 有 \(a + b\) 种解决方式。
乘法原理:若事件 \(A\) 分两步解决,第一步式有 \(a\) 种方案,第二个步有 \(b\) 种方案,则事件 \(A\) 有 \(a \times b\) 种解决方式。
排列数
一个 \(0 - n\) 的排列,有多少种不同的排列方式?
根据乘法原理,有 \(n \times (n - 1) \times (n - 2) \times \cdots \times 1 = n!\) 种方案。
那么从 \(n\) 个数中选出 \(m\) 个数进行排列,有多少种不同的排列方式?
根据乘法原理,有 \(n \times (n - 1) \times (n - 2) \times \cdots \times (n - m + 1) = \frac{n!}{(n - m)!}\) 种方案。
我们将这个答案记作
即排列数。
组合数
那么如果仅仅是从 \(n\) 个数中选出 \(m\) 个数,而不考虑排列顺序呢?
根据乘法原理,有 \(A_{n}^{m} = answer \times m!\),即有 \(\frac{A_{n}^{m}}{m!} = \frac{n!}{(n - m)!m!}\) 种方案。
我们将这个问题的答案记作
即组合数,组合数也可以写作 \(\binom{n}{m}\),读作 \(n\) choose \(m\)
除法原理
由推出组合数的方法,我们发现,若事件 \(A\) 有两种解决方式,共 \(n\) 种方案,其中一种方式有 \(a\) 种,那么另一种方式有 \(b = \frac{n}{a}\) 种方案。我们可以将这个原理称为除法原理(此处为笔者总结,实际上并不存在这个原理)。
圆排列
有 \(n\) 个不同元素,把它们排成一个圆,将旋转后一样的方案视为同一种,那么有多少种排列方式。
根据除法原理,我们有 \(n! / n = (n - 1)!\) 种方案。
同时,有乘法原理,我们也可以将这个问题看作是 \(n\) 个元素排成一行,然后将最后一个元素放到第一个元素的前面,那么根据乘法原理,我们有 \((n - 1)!\) 种方案。
指定子集大小的集合划分
有 \(n\) 个元素将他们分为三个集合,给定每个集合的大小分别为 \(n_a, n_b, n_c\),那么有多少种划分方式?
由组合数我们有 \(\binom{n}{n_a} \binom{n - n_a}{n_b}\) 种方案。
化简得,我们有 \(\frac{n!}{n_a!n_b!n_c!}\) 种方案。
我们将这种问题称为指定子集大小的集合划分问题。即给定 \(n\) 个元素,分为 \(k\) 个集合,每个集合的大小分别为 \(n_1, n_2, \ldots, n_k\),则该问题的答案为
多重集合的全排列
有一个多重集合中有 \(1\) 个 \(1\),\(2\) 个 \(2\), \(3\) 个 \(3\), \(\ldots\), \(m\) 个 \(m\),共有 \(n = \sum\limits_{i = 1}^{m} {i}\) 个元素。
那么根据乘法原理我们有 \(\frac{n!}{1!2!3!\cdots m!}\) 种方案。
插板法 & 方程解的个数
给定不定方程 \(x_1 + x_2 + \cdots + x_k = n\),其中 \(x_i, n\) 为正整数。
我们考虑,将其看成有 \(n\) 个球,\(k - 1\) 个隔板,将 \(n\) 个球分为 \(k\) 组的方案数,每两个隔板间的球数表示 \(x\), 不难发现两个问题是等价的。
根据这个转化我们得到这个问题的答案为 \(\binom{n - 1}{k - 1}\) 种方案。
二项式定理
形式:
证明:考虑每一项的系数,不妨设一项为 \(a^{n - k} b^k\),那么我们知道在计算的过程种我们选择了 \(k\) 个 \(a\),\(n - k\) 个 \(b\),根据组合数,我们有 \(\binom{n}{k}\) 种方案。
组合数的性质
性质1(组合数的递推式)
证明(性质一)
考虑这样的一道题:有 \(n\) 个元素,从中选出 \(m\) 个元素,使得他们两两不相邻,那么有几种选择方法?
方法一:
我们可以选择 \(m\) 个元素,保证他们右边的元素没有被选择,那么我们可以将这 \(m\) 个元素与他们右边相邻元素的二元组看作一个整体,那么原问题就被转化为从 \(n - m\) 个元素中选择 \(m\) 个元素,根据乘法原理我们有 \(\binom{n - m}{m}\) 种方案。
相信聪明的读者已经发现,这两个问题并不等价,为什么呢?
手模一下就可以发现,这种方法忽略了最优侧的元素被选择的情况。
我们考虑,计算出强制选择最右侧的数的方案数加上前面的答案,根据组合数我们有 \(\binom{n - m}{m - 1}\) 种方案。
所以原问题的答案为 \(\binom{n - m}{m} + \binom{n - m}{m - 1}\)。
方法二:
我们不妨在序列的结尾添加一个新的元素,根据上面的发现,我们知道,这个新加的元素并不会被选择,那么他就不会影响答案,根据上面的方法我们有 \(\binom{n - m + 1}{m}\) 种方案。
根据两种对问题的不同看法,我们得到一个恒等式:\(\binom{n - m + 1}{m} = \binom{n - m}{m} + \binom{n - m}{m - 1}\)。
令 \(n - m + 1 = n\),\(m = k\),我们就得到了 \(\binom{n}{k} = \binom{n - 1}{k} + \binom{n - 1}{k - 1}\)。
证毕。
性质2(组合数的对称性)
证明(性质二)
由组合意义我们不难发现,从 \(n\) 个元素中选出 \(k\) 个元素,等价于从 \(n\) 个元素中选出 \(n - k\) 个元素。
性质3
证明(性质三)
不难发现,原式可写作 \(\sum\limits_{k = 0}^{n} \binom{n}{k}(1 \times 1)\),由二项式定理我们有 \(\sum\limits_{k = 0}^{n} \binom{n}{k}(1 \times 1) = (1 + 1) ^ n = 2 ^ n\)
证毕。
性质4(范德蒙德卷积)
证明(性质四)
从组合意义考虑,我们发现在 \(n + m\) 个元素中选出 \(r\) 个元素,等价于从 \(m\) 个元素中选出 \(k\) 个元素,从 \(n\) 个元素中选出 \(r - k\) 个元素。
形式上有 \(\sum\limits_{k = 0}^{n} \binom{m}{k} \binom{n}{r - k} = \binom{m + n}{r}\)
证毕。
卡特兰数
令 \(Cat_n\) 为有 \(n\) 个节点的有根二叉树的个数。
当且仅当如下三个条件至少有一个成立时,两个二叉树视为不同的:
-
一棵二叉树为空,另一颗不为空。
-
两个二叉树的左子树不同。
-
两个二叉树的右子树不同。
我们可以枚举左子树大小,不难发现:
优化
我们使用上面的式子递推是 \(O(n ^ 2)\) 的,事实上我们可以使用组合数来优化这个式子。
我们知道
相关证明会在第五章中给出。
第二类斯特林数
考虑这样的一个问题,将 \(1, 2, \ldots, n\) 这 \(n\) 个元素分为 \(k\) 个非空的集合,有多少种划分方法?
两个分法是不同的当且仅当所分集 \(s_1, s_2, \ldots, s_k\) 是不同的。
我们将这个问题的答案记作 \(\left\{n \atop k\right\}\),即第二类斯特林数。
我们考虑,将元素 \(x\) 划分的方法有两种:
-
将 \(x\) 放入一个新的空集中。
-
将\(x\) 放入一个已经存在的集合中。
根据乘法原理和加法原理我们有
第 2 章 初等数论
本章及第六章中,在未特殊提及的情况下,我们都认为所有为正整数。
欧几里得算法
欧几里得算法是求两个正整数 \(a, b\) 的最大公约数的算法。
形式上:
证明:
不妨令 \(a = p_a \times \mathrm{{gcd}(a, b)}, b = p_b \times \mathrm{{gcd}(a, b)}\),其中 \(a < b\)。
则 \(\mathrm{gcd}(a, a - b) = \mathrm{gcd}(a, b) \times \mathrm{gcd}(p_a - p_b, p_a)\)
即 \(\mathrm{gcd}(a, a - b) \leq \mathrm{gcd}(a, b)\)
同时,反过来我们有 \(\mathrm{gcd}(a, a - b) \geq \mathrm{gcd}(a, b)\)
所以 \(\mathrm{gcd}(a, a - b) = \mathrm{gcd}(a, b)\)。
我们可以将 \(a \mod b\) 看作是多次减去 \(b\),所以我们可以将上面的式子改写为:
\(\mathrm{gcd}(a, b) = \mathrm{gcd}(b, a \bmod b)\)。
证毕。
递归代码实现如下:
std::function<int(int,int)> gcd = [&](int a, int b) -> int {return b == 0 ? a : gcd(b, a % b);}
不难发现在每次递归中 \(a\) 的大小最少减少一半,所以该算法的时间复杂度为 \(O(\log n)\)
裴蜀定理
给出一个二元一次不定方程:\(ax + by = \mathrm{gcd}(a, b)\)
若 \(\mathrm{gcd}(a, b) \mid ax +by\),则存在一对整数 \(x, y\) 使得方程成立。
证明:
令 \(a > b\)
考虑欧几里得算法的最后一步,此时 \(b = 0\),显然有一对整数 \(x = 1, y = 0\),使得 \(1 \times a + 0 \times 0 = \mathrm{gcd}(a, 0)\)
若 \(b > 0\),假设存在一组 \(x, y\),使得 \(bx + (a \mod b)y= \mathrm{gcd}(b, a \mod b)\)
将 \(a \mod b\) 写成 \(a - \left\lfloor {\frac{a}{b}} \right\rfloor \times b\),将括号拆开整理得 \(ay + b(x - \left\lfloor {\frac{a}{b}} \right\rfloor \times y)\)
令 \(x' = y, y' = x - \left\lfloor {\frac{a}{b}} \right\rfloor \times y\),有 \(ax' + by' = \mathrm{gcd}(a, b)\)
对欧几里得算法使用数学归纳法。
证毕。
扩展欧几里得算法
在上述关于裴蜀定理的证明中,同时给出了求解 \(x, y\) 的计算方法,该方法被称为扩展欧几里得算法
递归代码实现如下:
function<pair<int, pair<int,int>>(int,int)> extgcd = [&](int u, int v) -> pair<int, pair<int int>>
{
if (v == 0) return {u, {1, 0}};
auto res = extgcd(v, u % v);
int g = res.first;
int x1 = res.second.first;
int y1 = res.second.second;
return {g, { y1, x1 - (u / v) * y1 }};
};
该代码时间复杂度为 \(O(\log n)\)
唯一分解定理
对于唯一正整数 \(n\),存在唯一方法将其分解成若干质数的乘积。
形式上的:
该定理为我们提供了另一种看待数论的方法,
我们令 \(n\) 分解后,每项的次数为 \(c_1, c_2, c_3 \ldots c_n\) 则我们可以将任意自然数与每项的次数所形成的序列建立一一对应的映射关系。
于是我们可以对如下计算做出新定理:
令 \(a = p_1^{{c_1}_a}p_2^{{c_2}_a}p_3^{{c_3}_a} \ldots p_k^{{c_k}_a}, b = p_1^{{c_1}_b}p_2^{{c_2}_b}p_3^{{c_3}_b} \ldots p_k^{{c_k}_b}\)
即 \(a = \{{c_1}_a, {c_2}_a, {c_3}_a, \ldots {c_k}_a\}, b = \{{c_1}_b, {c_2}_b, {c_3}_b, \ldots {c_k}_b\}\)
两数相乘即为:\(\sum\limits_{i = 0}^{k} {c_i}_a + {c_i}_b\)
两数相除即为:\(\sum\limits_{i = 0}^{k} {c_i}_a - {c_i}_b\)
两数 \(\mathrm{gcd}\) 即为:\(\{\min({c_1}_a + {c_1}_b), \min({c_2}_a + {c_2}_b), \min({c_3}_a + {c_3}_b), \ldots \min({c_k}_a + {c_k}_b)\}\)
两数 \(\mathrm{lcm}\) 即为:\(\{\max({c_1}_a + {c_1}_b), \max({c_2}_a + {c_2}_b), \max({c_3}_a + {c_3}_b), \ldots \max({c_k}_a + {c_k}_b)\}\)
按照这种看法我们可以得到一个重要结论:\(\mathrm{gcd}(a, b) \times \mathrm{lcm}(a, b) = a \times b\)
同余的基本性质
1.\(a \equiv b \pmod{m} \iff a \pm c \equiv b \pm c \pmod{m}\)
2.\(a \equiv b \pmod{m} \iff a \times c \equiv b \times c \pmod{m}\)
注意:\(a \equiv b \pmod{m} \iff a / c \equiv b / c \pmod{m}\) 是错误的,因为不能保证 \(a / c, b / c\) 为整数。
逆元
根据上文我们知道,\(a \equiv b \pmod{m} \iff a / c \equiv b / c \pmod{m}\)不成立,那么我们能否用一种方式使得同余方程也可以像等式方程一个两边同时除以一个数的操作。
若 \(a \equiv bc \pmod{m}\), 为了满足这样的需求,我们需要找到一个 \(b^{-1}\),使得 \(a \times b^{-1} \equiv c \pmod{m}\),我们称这样的 \(b^{-1}\) 为 \(b\) 的逆元。
随之而来的问题是,这样的一个逆元一定存在吗?
我们注意到 \(b \times b^{-1} \equiv 1 \pmod{m}\),与原式是充要的。
令 \(b ^ {-1}\)为 \(x\),则有 \(bx \equiv 1 \pmod{m} \iff \exist{y}, {bx + my = 1}\)
根据裴蜀定理,我们有 \(bx \equiv 1 \pmod{m} \iff \exist{y}, {bx + my = 1} \iff \mathrm{gcd}(a, m) | 1 \iff \mathrm{gcd}(a, m) = 1\)
由此可知,\(b\)模\(m\)意义下存在逆元的充要条件为 \(\mathrm{gcd}(a, m) = 1\)
这就解释了为什么在算法竞赛中模数通常使用大质数。
逆元若存在,那么是唯一的。
线性不定方程
是否有解?
根据上文所提到的裴蜀定理即可证明,本处不在赘述。
如何求解?
使用上文所提到的扩展欧几里得算法就可以求出一组解,那么如何求出二元一次线性不定方程的另外几组解?
考虑将二元一次不定方程看作是二维平面上的一条直线,那么直线上任意一点坐标即为该二元一次不定方程的解。
费马小定理
内容:\(a^{p - 1} \equiv 1 \pmod{p}\) (p 为质数)
证明:
可以使用数学归纳法证明。若 \(a^{p - 1} \equiv 1 \pmod{p}\) 成立,即 \(a ^ p \equiv a \pmod{p}\) 成立。
考虑 \((a + 1) ^p\pmod{p}\),
由上一章讲到的二项式定理我们知道 \((a + 1) ^ p = a ^ p + \binom {p}{1} a^{p - 1} + \binom {p}{2} a^{p - 2} + \ldots + \binom {p}{p - 1} a + 1\)
根据组合数的公式我们知道 \(\binom{p}{1} = \frac{p\times (p - 1)\times(p - 2) \ldots 2\times 1}{(p - 1)! \times 1}\) 容易发现,对于所有的 \(\binom{p}{i}, ( 1\leq i \leq p - 1)\) 在模 \(p\) 意义下均为 \(0\)
所以我们就得到了如下式子:\((a + 1) ^ p \equiv a^p + 1 \pmod{p}\)
因为 \(a ^ p \equiv a \pmod{p}\)
所以 \((a + 1) ^ p \equiv a + 1 \pmod{p}\)
显然由 \(1 ^ p \equiv 1 \pmod{p}\)
根据数学归纳法可知:\(a ^ {p - 1} \equiv 1\pmod{p}\) (\(p\) 为质数)
证毕。
线性同余方程
形如:\(ax \equiv b \pmod{m}\) 的方程我们称为不定方程。
容易发现 \(x \equiv ba^{-1} \pmod{m}\)
可以使用扩展欧几里得算法与费马小定理求出 \(a^{-1}\),进而解出这一类方程。
拉格朗日插值法
拉格朗日插值法可以在给出 \(n + 1\) 个点的情况下,求出满足这 \(n\) 个点的多项式,我们称这个多项式为拉格朗日(插值)多项式。
具体求法:给定 \(n + 1\) 个点,分别为 \((x_1, y_1), (x_2, y_2), (x_3, y_3), \ldots ,(x_n, y_n)\),假设 \(x_i\) 互不相同,则根据拉格朗日插值我们得出的拉格朗日多项式为:
其中每个 \(\ell_i(x)\) 为拉格朗日基本多项式(或称插值基函数),其表达为:
不难发现,拉格朗日基本多项式的特点为在 \(x = x_j\) 处的取值为 \(1\),在其余点处取 \(0\)
不妨先看一组样例:
假设有某个二次多项式函数 \(f\),已知它在三个点上的取值为:
- \(f(4) = 10\)
- \(f(5) = 5.25\)
- \(f(6) = 1\)
要求 \(f(18)\) 的值。
首先写出每个拉格朗日基本多项式:
应用拉格朗日插值公式,可以得到 \(p(x)\) 的表达式(插值函数):
此时代入数值 \(x = 18\) 即可求出所需之值:
证明:
存在性
设给定的 \(n\) 个点为 \((x_1, y_1), (x_2, y_2), (x_3, y_3), \ldots (x_n, y_n)\),拉格朗日插值法的思路是寻找一个多项式,使得其在 \(x_j\) 处取 \(y_j\),在其余处取 \(0\)
拉格朗日多项式 \(L(x) := \sum\limits_{j = 0}^{n}y_j\ell_j(x)\) 就满足这个特性。
即将 \(x = x_i\) 带入得 \(L(x_i) := \sum\limits_{j = 0}^ny_j\ell_j(x_j) = 0 + 0 + 0 + \ldots + y_i + \ldots + 0 = y_i\)
考虑如何构造拉格朗日基本多项式,若想要在其余处取 \(0\) 只需要构造如下式子:\((x - x_1)(x - x_2)\ldots(x - x_{j - 1})(x - x_{j + 1})\ldots(x - x_n)\)
这个式子在 \(x = x_j\) 处的取值为 \((x_j - x_1)(x_j - x_2)\ldots(x_j - x_{j - 1})(x_j - x_{j + 1})\ldots(x_j - x_n)\) 因为 \(x_i\) 互不相同,所以该式不为 \(0\)。于是我们可以将这个多项式除以该式,则得到一个在在 \(x_j\) 处取 \(1\),在其余处取 \(0\) 的多项式,将这个多项式乘以 \(y_j\) 即可。
即:\(L(x) := \sum\limits_{j = 0}^{n}y_j\ell_j(x)\)
唯一性
次数不超过 \(n\) 的拉格朗日多项式只有一个。若有两个多项式 \(P_1, P_2\) 满足拉格朗日多项式,那么 \(P_1 - P_2\) 在 \(k + 1\) 个点上的取值为 \(0\),则 \(P_1 - P_2\) 是 \((x - x_1)(x - x_2)\ldots(x - x_n)\) 的倍数,若 \(P_1 - P_2\) 不等于 \(0\),那么次数就一定不小于 \(k + 1\),因为 \(P_1, P_2\) 都是 \(k\) 次多项式,则 \(P_1 - P_2 = 0\),即 \(P_1 = P_2\)
中国剩余定理
给出一个同余方程组:
其中 \(b_1, b_2, \ldots, b_n\) 互质
求出满足方程的一组解。考虑拉格朗日插值的思路。构造一组数 \(f_i\),使得:
令 \(x = \sum\limits_{i = 1} ^{n} f_i\) 即可。
令 \(m_i = \prod\limits_{j = 1, j \ne i}^n b_j\), \(M_i\) 为 \(b_i\) 的逆元。
则
即
扩展中国剩余定理
给出一个同余方程组:
并不保证 \(b_1, b_2, \ldots b_n\) 互质。
因为不能保证模数互质,所以我们不能找到一些数的逆元,那么就不能像中国剩余定理那样进行构造。
不妨先考虑两个方程的情况。
由前两个方程我们可以得出如下不定方程:
将右边两个式子相减,得:
根据上文提到的扩展欧几里得算法,我们可以求出这个二元不定方程的一组解,于是得到下面这个式子:
求解即可。
若是多组方程,则按照上述形式,将方程两两合并即可。
第 3 章 线性代数
矩阵的运算
矩阵加法:对于两个 \(n \times m\) 的矩阵 \(A\), \(B\),我们定义矩阵的加法为 \(A + B = C \iff a_{i,j} + B_{i,j} = C_{i,j}\)
矩阵的数乘:对于一个矩阵 \(A\),我们定义矩阵的数乘为 \((cA)_{i,j} = c(A_{i,j})\)
矩阵乘法:对于两个为别为 \(n \times m\),\(m \times r\) 的矩阵 \(A, B\),我们定义矩阵乘法为
不难发现,矩阵乘法满足结合律但不满足交换律。
注意:矩阵没有除法。
线性基
在第 0 章的“张出(span)”这一部分,我们提到一个命题:任取 \(n\) 个向量 \(\vec{v_1}, \vec{v_2}, \vec{v_3}, \ldots, \vec{v_n}\),它们所有的线性组合构成空间 \(\mathrm{V}\),其实他的逆命题:任取一个空间 \(\mathrm{V}\),他都能表示 \(n\) 个向量的所有线性组合,也是正确的。我们称这 \(n\) 个向量为这一线性空间的生成元。如果一个生成元是最小的,那么我们将这 \(n\) 个向量称为这个空间的线性基。
线性变换
变换是空间中的函数,把一个向量映射为另一个向量。
我们称一个变换是线性变换当且仅当该变换具有线性性。
对于线性性,我们做出如下定义,对于一个变换 \(f\),当它满足如下性质则称其有线性性:
- \(f(\vec{a} + \vec{b}) = f(\vec{a}) + f(\vec{b})\)
- \(f(c\vec{a}) = cf(\vec{a})\)
不难发现在线性变换中原点的位置不会改变。
有趣的是一个线性变换可以用唯一的矩阵表示。所以对于线性递推序列我们可以用矩阵来表示其递推关系。
高斯消元
给出如下线性方程组:
那么我们可以用矩阵来表示这个方程组:
即 \(A \vec{x} = \vec{b}\)
一句话来说,高斯消元就是通过三种基本变换将矩阵转化为最简阶梯矩阵。
其中三种基本变换为:
-
交换两行
-
将一行乘以一个非零常数
-
将一行加另一行的倍数
最简阶梯矩阵定义为:
-
每一行的首个非零元素为 \(1\)
-
首个非零元素所在列的其他元为 \(0\)
具体的:
-
初始化 \(i = 1\)
-
在矩阵中找到一个“没用过”的行 \(j\),使得 \(a_{j,i} \neq 0\)
-
交换第 \(i\) 行和第 \(j\) 行
-
将第 \(i\) 行的首个非零元素化为 \(1\)
-
将第 \(i\) 行的倍数加到其他行,使得第 \(i\) 列的其他元素化为 \(0\)
-
\(i \gets i + 1\),重复步骤 \(2\) 直到所有列都处理完毕
让我们通过一个例子来理解高斯消元的过程:
考虑如下 3 元 3 次方程组:
我们将其转化为增广矩阵形式:
步骤 1:消去第 1 列下方元素
-
以第 1 行 \(R_1\) 为基准,消去 \(a_{2,1}=-3\):
\[R_2 \leftarrow R_2 + \tfrac{3}{2}R_1 \quad\Longrightarrow\quad R_2 = [0,\; 0.5,\; 0.5\;|\; -11 + \tfrac{3}{2}\cdot 8] = [0,\;0.5,\;0.5\;|\;1]. \] -
消去 \(a_{3,1}=-2\):
\[R_3 \leftarrow R_3 + R_1 \quad\Longrightarrow\quad R_3 = [0,\;2,\;1\;|\;5]. \]
此时矩阵变为:
步骤 2:消去第 2 列下方元素
-
首先,将第 2 行归一化(把主元变为 1):
\[R_2 \leftarrow \tfrac{1}{0.5}R_2 \quad\Longrightarrow\quad R_2 = [0,\;1,\;1\;|\;2]. \] -
以新 \(R_2\) 为基准,消去 \(R_3\) 中第 2 列的 2:
\[R_3 \leftarrow R_3 - 2R_2 \quad\Longrightarrow\quad R_3 = [0,\;0,\;-1\;|\;1]. \]
此时矩阵变为上三角形:
- 回代求解
从最后一行开始,依次向上回代:
- 第三行:
\(-1\cdot z = 1 \quad\Longrightarrow\quad z = -1.\) - 第二行:
\(y + 1\cdot z = 2 \quad\Longrightarrow\quad y + (-1) = 2 \;\Longrightarrow\; y = 3.\) - 第一行:
\(2x + y - z = 8\)
代入 \(y=3,\,z=-1\):
\(2x + 3 - (-1) = 8 \;\Longrightarrow\; 2x + 4 = 8 \;\Longrightarrow\; x = 2.\)
最终解为:

浙公网安备 33010602011771号