8.15.8 ACM-ICPC 线性代数: 线性基
引言
在线性代数中,线性基(或称基底)是描述向量空间结构的重要工具。理解线性基的概念和性质对于解决许多数学和编程问题至关重要。本文将详细介绍线性基的定义、性质以及其在实际问题中的应用。
线性基的定义
线性基是线性空间中的一个向量组,它具有生成整个空间的能力,同时向量组中的向量彼此线性无关。形式上,如果 VVV 是一个线性空间,向量组 {v1,v2,…,vn}\{v_1, v_2, \ldots, v_n\}{v1,v2,…,vn} 满足以下两个条件:
-
生成整个空间:任何 VVV 中的向量都可以表示为 {v1,v2,…,vn}\{v_1, v_2, \ldots, v_n\}{v1,v2,…,vn} 的线性组合,即对于任意 v∈Vv \in Vv∈V,存在一组标量 a1,a2,…,ana_1, a_2, \ldots, a_na1,a2,…,an 使得 v=a1v1+a2v2+⋯+anvnv = a_1 v_1 + a_2 v_2 + \cdots + a_n v_nv=a1v1+a2v2+⋯+anvn
-
线性无关:向量组 {v1,v2,…,vn}\{v_1, v_2, \ldots, v_n\}{v1,v2,…,vn} 中的向量彼此线性无关,即如果 a1v1+a2v2+⋯+anvn=0a_1 v_1 + a_2 v_2 + \cdots + a_n v_n = 0a1v1+a2v2+⋯+anvn=0 则 a1=a2=⋯=an=0a_1 = a_2 = \cdots = a_n = 0a1=a2=⋯=an=0。
满足上述条件的向量组 {v1,v2,…,vn}\{v_1, v_2, \ldots, v_n\}{v1,v2,…,vn} 称为 VVV 的一个基,向量组中向量的数量 nnn 称为 VVV 的维数。
基的存在性与唯一性
存在性
对于任意有限维线性空间 VVV,都存在一个基。可以通过高斯消元法等算法从任意向量组中找到一个极大线性无关组,进而得到一个基。
唯一性
虽然一个线性空间可以有多个不同的基,但所有基的向量数量(即维数)都是相同的。因此,维数是线性空间的一个不变量。
例子
- 欧几里得空间 Rn\mathbb{R}^nRn
标准基 {e1,e2,…,en}\{e_1, e_2, \ldots, e_n\}{e1,e2,…,en},其中 ei=(0,0,…,1,…,0)e_i = (0, 0, \ldots, 1, \ldots, 0)ei=(0,0,…,1,…,0) 即第 iii 个分量为 1,其余分量为 0。
- 多项式空间 P[x]\mathbb{P}[x]P[x]
对于多项式空间 Pn[x]\mathbb{P}_n[x]Pn[x],基为 {1,x,x2,…,xn}\{1, x, x^2, \ldots, x^n\}{1,x,x2,…,xn}
- 矩阵空间 Pm×n\mathbb{P}^{m \times n}Pm×n
基为标准矩阵,其中每个矩阵只有一个元素为 1,其余元素为 0。
线性基的性质
- 唯一表示:每个向量都可以唯一地表示为基向量的线性组合。
- 维数不变性:所有基的向量数量相同。
- 扩展性:任意线性无关向量组可以扩展成一个基。
- 缩减性:生成整个空间的任意向量组可以缩减成一个基。
基变换
基变换是将向量从一个基转换到另一个基的过程。设 B={v1,v2,…,vn}B = \{v_1, v_2, \ldots, v_n\}B={v1,v2,…,vn} 和 B′={u1,u2,…,un}B' = \{u_1, u_2, \ldots, u_n\}B′={u1,u2,…,un} 是 VVV 的两个基。则存在一个可逆矩阵 PPP 使得 ui=∑j=1nPjivju_i = \sum_{j=1}^n P_{ji} v_jui=∑j=1nPjivj 矩阵 PPP 称为基变换矩阵。
应用
线性方程组的解
在求解线性方程组时,选择合适的基可以简化计算。特别是对角化基和正交基在计算中尤为重要。
数据降维
主成分分析(PCA)是一种基于线性代数的降维方法,通过选择主成分基,可以减少数据维度,提高计算效率。
结论
线性基是线性代数的重要概念,理解基的定义、性质和应用对于解决实际问题具有重要意义。在ACM-ICPC竞赛中,掌握线性基的使用技巧可以有效地解决复杂的数学和计算问题。
8.15.8 ACM-ICPC 线性代数: 线性基
引言
回想高中数学立体几何中基向量的概念,我们可以在三维欧氏空间中找到一组基向量 i\boldsymbol{i}i、j\boldsymbol{j}j、k\boldsymbol{k}k,之后空间中任意一个向量都可以由这组基向量表示。换句话说,我们可以通过有限的基向量来描述无限的三维空间,这足以体现基向量的重要性。三维欧氏空间是特殊的线性空间,三维欧氏空间的基向量在线性空间中就被推广为了线性基。
在ACM-ICPC竞赛中,有关线性基的应用一般只涉及两类线性空间:n维实线性空间 Rn\mathbf{R}^nRn 和 n维布尔域线性空间 Z2n\mathbf{Z}_2^nZ2n。我们会在应用一节中详细介绍。若您不熟悉线性代数,则推荐从应用部分开始阅读。
定义
线性基是线性空间的一组基,是研究线性空间的重要工具。称线性空间 VVV 的一个极大线性无关组为 VVV 的一组 Hamel 基或线性基,简称基。
规定线性空间 {θ}\{\theta\}{θ} 的基为空集。
可以证明任意线性空间均存在线性基。我们定义线性空间 VVV 的维数为线性基的元素个数(或势),记作 dimV\dim VdimV。
性质
对于有限维线性空间 VVV,设其维数为 nnn,则:
- VVV 中的任意 n+1n+1n+1 个向量线性相关。
- VVV 中的任意 nnn 个线性无关的向量均为 VVV 的基。
- 若 VVV 中的任意向量均可被向量组 a1,a2,…,ana_1, a_2, \dots, a_na1,a2,…,an 线性表出,则其是 VVV 的一个基。
证明
任取 VVV 中的一组基 b1,b2,…,bnb_1, b_2, \dots, b_nb1,b2,…,bn,由已知条件,向量组 b1,b2,…,bnb_1, b_2, \dots, b_nb1,b2,…,bn 可被 a1,a2,…,ana_1, a_2, \dots, a_na1,a2,…,an 线性表出,故 n=rank{b1,b2,…,bn}≤rank{a1,a2,a3}≤nn = \operatorname{rank}\{b_1, b_2, \dots, b_n\} \leq \operatorname{rank}\{a_1, a_2, a_3\} \leq nn=rank{b1,b2,…,bn}≤rank{a1,a2,a3}≤n 因此 rank{a1,a2,…,an}=n\operatorname{rank}\{a_1, a_2, \dots, a_n\} = nrank{a1,a2,…,an}=n。
VVV 中任意线性无关向量组 a1,a2,…,ama_1, a_2, \dots, a_ma1,a2,…,am 均可通过插入一些向量使得其变为 VVV 的一个基。
子空间维数公式
令 V1,V2V_1, V_2V1,V2 是关于 P\mathbb{P}P 的有限维线性空间,且 V1+V2V_1+V_2V1+V2 和 V1∩V2V_1 \cap V_2V1∩V2 也是有限维的,则 dimV1+dimV2=dim(V1+V2)+dim(V1∩V2)\dim V_1 + \dim V_2 = \dim(V_1 + V_2) + \dim(V_1 \cap V_2)dimV1+dimV2=dim(V1+V2)+dim(V1∩V2)
证明
设 dimV1=n1,dimV2=n2,dim(V1∩V2)=m\dim V_1 = n_1, \dim V_2 = n_2, \dim(V_1 \cap V_2) = mdimV1=n1,dimV2=n2,dim(V1∩V2)=m。
取 V1∩V2V_1 \cap V_2V1∩V2 的一组基 a1,a2,…,ama_1, a_2, \dots, a_ma1,a2,…,am,将其分别扩充为 V1V_1V1 和 V2V_2V2 中的基:a1,a2,…,am,b1,b2,…,bn1−ma_1, a_2, \dots, a_m, b_1, b_2, \dots, b_{n_1-m}a1,a2,…,am,b1,b2,…,bn1−m 和 a1,a2,…,am,c1,c2,…,cn2−ma_1, a_2, \dots, a_m, c_1, c_2, \dots, c_{n_2-m}a1,a2,…,am,c1,c2,…,cn2−m。
接下来只需证明向量组 a1,a2,…,am,b1,b2,…,bn1−m,c1,c2,…,cn2−ma_1, a_2, \dots, a_m, b_1, b_2, \dots, b_{n_1-m}, c_1, c_2, \dots, c_{n_2-m}a1,a2,…,am,b1,b2,…,bn1−m,c1,c2,…,cn2−m 线性无关即可。
设 ∑i=1mriai+∑i=1n1−msibi+∑i=1n2−mtici=θ\sum_{i=1}^m r_i a_i + \sum_{i=1}^{n_1-m} s_i b_i + \sum_{i=1}^{n_2-m} t_i c_i = \theta∑i=1mriai+∑i=1n1−msibi+∑i=1n2−mtici=θ
则 ∑i=1n2−mtici=−∑i=1mriai−∑i=1n1−msibi\sum_{i=1}^{n_2-m} t_i c_i = -\sum_{i=1}^m r_i a_i - \sum_{i=1}^{n_1-m} s_i b_i∑i=1n2−mtici=−∑i=1mriai−∑i=1n1−msibi
注意到上式左边在 V2V_2V2 中,右边在 V1V_1V1 中,故两边均在 V1∩V2V_1 \cap V_2V1∩V2 中,因此
性质
令 V1,V2V_1, V_2V1,V2 是关于 P\mathbb{P}P 的有限维线性空间,且 V1+V2V_1+V_2V1+V2 和 V1∩V2V_1 \cap V_2V1∩V2 也是有限维的,则下列诸款等价:
例子
R2\mathbb{R}^2R2 的基
-
如图,uuu、vvv 是一组基。
-
如图,uuu、vvv 是一组基。
-
如图,uuu、vvv 不是一组基,因为 u=−vu = -vu=−v。
-
如图,uuu、vvv、www 不是一组基,因为 u+4v+6w=θu + 4v + 6w = \thetau+4v+6w=θ。
正交基与单位正交基
若线性空间 VVV 的一组基 BBB 满足 ∀b,b′∈B, (b,b′)≠0 ⟺ b=b′\forall b, b' \in B,~(b, b') \ne 0 \iff b = b'∀b,b′∈B, (b,b′)=0⟺b=b′(即两两正交),则称这组基是正交基。
若线性空间 VVV 的一组正交基 BBB 还满足 ∀b∈B, ∣b∣=(b,b)=1\forall b \in B,~|b| = \sqrt{(b, b)} = 1∀b∈B, ∣b∣=(b,b)=1,则称这组基是单位正交基。
任意有限维线性空间 VVV 的基都可以通过Schmidt正交化变换为正交基。
应用
根据前文内容,我们可以利用线性基实现:
- 求给定向量组的秩;
- 对给定的向量组,找到一组极大线性无关组(或其张成的线性空间的一组基);
- 向给定的向量组插入某些向量,在插入操作后的向量组中找到一组极大线性无关组(或其张成的线性空间的一组基);
- 对找到的一组极大线性无关组(或基),判断某向量能否被其线性表出;
- 对找到的一组极大线性无关组(或基),求其张成的线性空间中的特殊元素(如最大元、最小元等)。
在ACM-ICPC竞赛中,我们一般将n维实线性空间 Rn\mathbf{R}^nRn 下的线性基称为实数线性基,n维布尔域线性空间 Z2n\mathbf{Z}_2^nZ2n 下的线性基称为异或线性基。
构造方法
因为异或线性基与实数线性基没有本质差别,所以接下来以异或线性基为例,实数线性基版本的代码只需做一点简单修改即可。
贪心法
对原集合的每个数 ppp 转为二进制,从高位向低位扫,对于第 xxx 位是 1 的,如果 axa_xax 不存在,那么令 ax←pa_x \leftarrow pax←p 并结束扫描,如果存在,令 p←p xor axp \leftarrow p \text{ xor } a_xp←p xor ax。
查询原集合内任意几个元素 xor\text{xor}xor 的最大值,只需将线性基从高位向低位扫,若 xor\text{xor}xor 上当前扫到的 axa_xax 答案变大,就把答案异或上 axa_xax。
为什么能行呢?因为从高往低位扫,若当前扫到第 iii 位,意味着可以保证答案的第 iii 位为 1,且后面没有机会改变第 iii 位。
查询原集合内任意几个元素 xor\text{xor}xor 的最小值,就是线性基集合所有元素中最小的那个。
查询某个数是否能被异或出来,类似于插入,如果最后插入的数 ppp 被异或成了 0,则能被异或出来。
代码(洛谷 P3812 【模板】线性基)
#include <bits/stdc++.h>
using ull = unsigned long long;
ull p[64];
void insert(ull x) {
for (int i = 63; ~i; --i) {
if (!(x >> i)) // x 的第 i 位是 0
continue;
if (!p[i]) {
p[i] = x;
break;
}
x ^= p[i];
}
}
int main() {
int n;
scanf("%d", &n);
ull a;
for (int i = 1; i <= n; ++i) {
scanf("%llu", &a);
insert(a);
}
ull ans = 0;
for (int i = 63; ~i; --i) {
ans = std::max(ans, ans ^ p[i]);
}
printf("%llu\n", ans);
return 0;
}
高斯消元法
高斯消元法相当于从线性方程组的角度去构造线性基,正确性显然。
代码(洛谷 P3812 【模板】线性基)
#include <bits/stdc++.h>
using ull = unsigned long long;
const int MAXN = 1e5 + 5;
ull deg(ull num, int deg) { return num & (1ull << deg); }
ull a[MAXN];
int main() {
int n;
scanf("%d", &n);
for (int i = 1; i <= n; ++i) scanf("%llu", &a[i]);
int row = 1;
for (int col = 63; ~col && row <= n; --col) {
for (int i = row; i <= n; ++i) {
if (deg(a[i], col)) {
std::swap(a[row], a[i]);
break;
}
}
if (!deg(a[row], col)) continue;
for (int i = 1; i <= n; ++i) {
if (i == row) continue;
if (deg(a[i], col)) {
a[i] ^= a[row];
}
}
++row;
}
ull ans = 0;
for (int i = 1; i < row; ++i) {
ans ^= a[i];
}
printf("%llu\n", ans);
return 0;
}
自己的理解
通过学习线性基的概念和应用,我们可以更好地理解向量空间的结构和性质。在编程竞赛中,线性基不仅可以帮助我们简化复杂的数学计算,还能提高算法的效率。以下是我对线性基的一些理解和总结:
-
线性基的实质:线性基是一组线性无关的向量,它们可以生成整个向量空间。通过线性基,我们可以用有限的向量表示整个向量空间中的任意向量。这使得线性基在数学和计算中的应用非常广泛。
-
异或线性基的应用:在编程竞赛中,异或线性基常用于解决与位操作相关的问题。通过构造异或线性基,我们可以高效地求解一些看似复杂的问题,例如求数组中所有子集的异或和的最大值。
-
贪心法与高斯消元法:这两种方法都是构造线性基的有效手段。贪心法适用于处理实际问题,效率较高;而高斯消元法更为严谨,适用于理论证明和数学研究。在实际应用中,我们可以根据具体问题选择合适的方法。
-
代码实现与优化:在实现线性基的过程中,我们需要注意代码的效率和正确性。例如,在插入新向量时,需要从高位到低位进行扫描,以确保线性基的有效性。同时,我们还可以根据具体问题进行代码优化,提高算法的运行效率。
小结
通过这道题目,我们学习了如何构造线性基,并利用线性基求解数组中所有子集的异或和最大值的问题。我们了解了线性基的重要性质以及其在实际编程中的应用。线性基可以帮助我们简化复杂的数学计算和编程问题,提高算法的效率。在编程竞赛中,掌握线性基的概念和应用是非常重要的,它可以为我们提供强大的工具来解决各种复杂问题。