多年前写的笔记,由 gpt-4o-mini 整合及提供代码,欢迎纠错。
1. 向量与线性空间
1.1 向量的定义与基本操作
- 向量:向量是具有大小和方向的量,可以在一维、二维或更高维空间中表示。在编程中,向量通常表示为一维数组。
- 向量加法:两个向量的加法是对应元素相加。例如,对于二维向量 \(v_1 = (x_1, y_1)\) 和 \(v_2 = (x_2, y_2)\),它们的和是 \(v_1 + v_2 = (x_1 + x_2, y_1 + y_2)\)。
- 数乘:一个向量与一个标量(实数或常数)相乘,称为数乘。例如,对于向量 \(v = (x, y)\) 和标量 \(k\),它们的数乘是 \(k \cdot v = (k \cdot x, k \cdot y)\)。
- 点积:两个向量的点积(内积)是它们对应元素的乘积的和。例如,二维向量 \(v_1 = (x_1, y_1)\) 和 \(v_2 = (x_2, y_2)\) 的点积是 \(v_1 \cdot v_2 = x_1 \cdot x_2 + y_1 \cdot y_2\)。
1.2 线性空间(向量空间)
-
定义:线性空间是一个向量的集合,其中的元素(向量)可以进行向量加法和数乘操作,并且满足一些基本的代数性质。常见的线性空间有欧几里得空间、矩阵空间等。
-
线性空间的公理:线性空间需要满足以下性质:
- 加法封闭性:对于任何两个向量 \(v_1\) 和 \(v_2\),它们的和 \(v_1 + v_2\) 仍然在该空间内。
- 数乘封闭性:对于任何向量 \(v\) 和标量 \(k\),数乘 \(k \cdot v\) 仍然在该空间内。
- 存在零向量:存在一个零向量 \(0\),使得对任意向量 \(v\),有 \(v + 0 = v\)。
- 存在负向量:对于每个向量 \(v\),存在一个向量 \(-v\),使得 \(v + (-v) = 0\)。
-
基与维度:
- 线性基:线性空间中一组极大线性无关的向量称为该空间的基。任何一个空间中的向量都可以表示为基向量的线性组合。
- 维度:线性空间的维度是其基中向量的个数。
2. 矩阵基础知识
2.1 矩阵
矩阵是一个按行和列排列的二维数组。矩阵常用于表示线性方程组、线性变换等。一个 \(m \times n\) 的矩阵由 \(m\) 行 \(n\) 列的元素构成。
示例:
2.2 矩阵的秩
矩阵 \(A\) 的秩(记作 \(rank(A)\))是矩阵中线性无关的行或列的最大数目。换句话说,矩阵的秩反映了矩阵在其行空间或列空间中的维度。
对于一个 \(m×n\) 的矩阵 \(A\),它的秩有以下几种等价的定义:
- 最大线性无关行数:矩阵的秩等于矩阵中最大数量的线性无关行。
- 最大线性无关列数:矩阵的秩等于矩阵中最大数量的线性无关列。
- 行空间的维度:矩阵的秩等于其行空间的维度。
- 列空间的维度:矩阵的秩等于其列空间的维度。
2.3 矩阵的加法(减法)
两个同型矩阵(即行数和列数相同)可以进行加法,方法是对应元素相加。
2.4 矩阵的数乘
一个矩阵可以与一个标量进行数乘,方法是将矩阵中的每个元素都乘以该标量。
2.5 矩阵的乘法
两个矩阵相乘的条件是第一个矩阵的列数等于第二个矩阵的行数。矩阵乘法的元素是通过按行列进行乘法和求和得到的。
2.6 矩阵的转置
矩阵的转置是将矩阵的行与列交换。
2.7 矩阵的初等行变换
在初等行变换后新矩阵等价于原矩阵。
初等行变换包括三种基本操作,分别是:
-
行交换(Row Swap):
- 将矩阵的两行交换。即,将矩阵的第 \(i\) 行和第 \(j\) 行互换。
- 例如,对于矩阵 \(A\),行交换操作可以表示为:\[R_{i \leftrightarrow j}(A) \]
-
行倍加(Row Scaling):
- 将矩阵的某一行乘以一个非零常数。
- 例如,将矩阵的第 \(i\) 行乘以标量 \(c\):\[R_{i \to c \cdot R_i}(A) \]
-
行加倍(Row Replacement):
- 将矩阵的某一行加上另一行的倍数。例如,将第 \(i\) 行加上第 \(j\) 行的 \(c\) 倍,结果更新为第 \(i\) 行:\[R_{i \to R_i + c \cdot R_j}(A) \]
- 将矩阵的某一行加上另一行的倍数。例如,将第 \(i\) 行加上第 \(j\) 行的 \(c\) 倍,结果更新为第 \(i\) 行:
这三种操作可以单独使用,也可以结合使用,目的是简化矩阵或将其转化为某种标准形式。
2.8 其它
增广矩阵、阶梯型矩阵、上三角矩阵……
3. 高斯消元法与高斯约旦消元法
OI-wiki 中所写的大多数人知道的高斯消元其实是高斯约旦消元。原始的高斯消元仅仅用于行列式求值。
3.1 高斯消元法
高斯消元法(Gaussian Elimination)是一种求解线性方程组的经典算法,它通过行变换将系数矩阵化为上三角形或阶梯形,从而便于回代求解。
步骤:
主元选择:对每一列,选择绝对值最大的元素作为主元,进行行交换。
消元:通过行变换消去当前列的下方元素,使得矩阵变为上三角形。
回代:从最后一行开始,逐行回代求解未知数。
部分代码(高斯消元法)
3.2 高斯约旦消元法
高斯约旦消元法(Gauss-Jordan Elimination)是高斯消元法的一个扩展,它不仅将矩阵转化为上三角形,还将其转换为 对角矩阵(主对角线上的元素为 1)。此方法常用于求解矩阵的逆和对行列式求值。
步骤:
- 主元选择:选择绝对值最大的元素作为主元,进行行交换。
- 消元:消去当前列的所有元素,使得对角线上的元素为 1,其他元素为 0。
部分代码(高斯约旦消元法)
double a[N][N]; // a[i][j] 表示第 i 个方程中第 j 个元的系数,a[i][n+1] 为等号右侧的常数项
void Gauss() {for (int i = 1; i <= n; i++) {int mxo = i;for (int j = 1; j <= n; j++) {if (fabs(a[j][i]) > fabs(a[mxo][i])) mxo = j;}// 行交换for (int j = 1; j <= n + 1; j++) swap(a[i][j], a[mxo][j]);if (fabs(a[i][i]) < eps) continue; // 无解或有无数解// 消元for (int j = 1; j <= n; j++) {if (i == j) continue;double tmp = a[j][i] / a[i][i];for (int k = i; k <= n + 1; k++) {a[j][k] -= a[i][k] * tmp;}}}
}
4. 求解逆矩阵
逆矩阵(Inverse Matrix)是指对于一个 \(n \times n\) 的矩阵 \(A\),若存在一个矩阵 \(B\),使得 \(A \times B = B \times A = I_n\),则称 \(B\) 为 \(A\) 的逆矩阵,记作 \(A^{-1}\)。
通过高斯约旦消元法可以计算矩阵的逆:
步骤:
- 将矩阵 \(A\) 扩展为 \([A | I_n]\)。
- 通过高斯约旦消元,将左边的 \(A\) 变为单位矩阵,右边就变为 \(A^{-1}\)。
部分代码(求逆矩阵)
bool Inverse() {for (int i = 1; i <= n; i++) {if (fabs(a[i][i]) < eps) return false; // 不可逆for (int j = 1; j <= n; j++) {if (i != j) {double tmp = a[j][i] / a[i][i];for (int k = 1; k <= 2 * n; k++) {a[j][k] -= a[i][k] * tmp;}}}}return true;
}
5. 行列式求值
行列式是一个与矩阵紧密相关的量,常用于描述矩阵对应的线性变换的几何特性。行列式的值表示矩阵所对应的变换在几何上的伸缩因子(如面积或体积的变化)。
5.1 行列式的定义与计算
行列式是一个标量,可以通过递归方法(按行或按列展开)计算。对于 \(2 \times 2\) 和 \(3 \times 3\) 矩阵,行列式有简便的计算公式。
\(2 \times 2\) 矩阵行列式:
\(3 \times 3\) 矩阵行列式:
对于更高维度的矩阵,行列式的计算可以通过递归展开来进行。
部分代码(行列式计算)
double det(int n, double a[N][N]) {double res = 1;for (int i = 1; i <= n; i++) {if (fabs(a[i][i]) < eps) return 0; // 行列式为 0res *= a[i][i];}return res;
}
5.2 行列式的几何意义
行列式可以解释为由矩阵的行或列向量所构成的超平行多面体的有向面积或体积。它是描述线性变换对几何图形的影响的重要量。例如,在二维空间中,行列式的绝对值表示由矩阵的列向量所形成的平行四边形的面积。
6. 模意义下的线性代数
6.1 模矩阵的加法与乘法
模意义下的矩阵加法和乘法与普通矩阵加法和乘法相同,只是每次计算时都要对模 \(p\) 取余。
6.2 模意义下的高斯消元法
在模意义下,消元法也可以在有限域上进行,但需要特别注意矩阵中元素的运算是模 \(p\) 的运算。
步骤:
- 选择主元:与普通高斯消元法相同,首先需要选择主元并进行行交换。
- 消元:消去当前列的下方元素,所有的运算都在模 \(p\) 的有限域中进行。
部分代码(模意义下的高斯消元法)
void GaussMod(int n, int a[N][N], int p) {for (int i = 1; i <= n; i++) {int mxo = i;for (int j = i + 1; j <= n; j++) {if (abs(a[j][i]) > abs(a[mxo][i])) mxo = j;}for (int j = 1; j <= n; j++) swap(a[i][j], a[mxo][j]);if (a[i][i] == 0) continue; // 无解int inv = modInverse(a[i][i], p); // 求模逆for (int j = i + 1; j <= n; j++) {int tmp = a[j][i] * inv % p;for (int k = i; k <= n; k++) {a[j][k] = (a[j][k] - a[i][k] * tmp % p + p) % p;}}}
}
6.3 异或线性空间
它是一个有限的向量空间,其中向量的加法是通过异或操作来进行的。一个向量空间可以通过一组基向量来表示,任何一个向量都可以表示为基向量的异或组合。
异或线性空间相当于模 \(2\) 意义下的线性空间。
在异或线性空间中,运算是通过二进制位的异或运算进行的,主要用于处理与二进制相关的算法问题,如 异或基 的构建。
部分代码(异或线性基)
ll base[55], ans;
bool insert(ll x) {for (int i = 50; i >= 0; i--) {if (x >> i & 1) {if (base[i]) x ^= base[i];else {base[i] = x;return 1;}}}return 0;
}