线性代数学习笔记

【定义】

  1. 向量:每个向量由若干个标量(数)组成,每个标量都来自同一个域 \(F\)。若一个向量包含 \(k\) 个标量,称其为 \(k\) 维向量。

  2. 向量空间 \(V\):由若干个向量组成。需要满足以下条件:

    1. \(V\) 中的向量满足加法交换律和加法结合律。

    2. \(V\) 中存在 \(0\) 向量,\(\vec{0}+\vec{u}=\vec{u}\)

    3. \(\vec{u}\in V\),则 \(-\vec{u}\in V\)

    4. \(a,b\) 为标量,\(a(b\vec{u})=(ab)\vec{u},(a+b)\vec{u}=a\vec{u}+b\vec{u}\)

    5. \(a\) 为标量,\(a(\vec{u}+\vec{v})=a\vec{u}+a\vec{v}\)

  3. 线性表示:若有向量 \(\vec{v},\vec{a_1}\sim\vec{a_n}\),且存在一组标量 \((k_1\sim k_n)\) 使得 \(\vec{v}=\displaystyle\sum_{i=1}^nk_i\vec{a_i}\),则 \(\vec{v}\) 可被 \(\vec{a_1}\sim\vec{a_n}\) 线性表示。

  4. 线性相关:对于一个向量空间 \(V\) 内的 \(n\) 个向量 \((\vec{v_1},\vec{v_2},\dots,\vec{v_n})\),若存在一组标量 \((a_1,a_2,\dots,a_n)\) 满足 \(a_1\sim a_n\) 不全为 \(0\)\(\displaystyle\sum_{i=1}^n a_i\vec{v_i}=\vec{0}\),则称 \(\vec{v_1}\sim \vec{v_n}\) 线性相关。

    线性相关还有另外一个表述方式\(\forall i\in [1,n]\cap\mathbb{Z},\vec{v_i}\) 不可被 \(\{\vec{v_1}\sim\vec{v_n}\}/\{\vec{v_i}\}\) 线性表示。

  5. 生成空间:对于一组向量 \(\vec{v_1}\sim\vec{v_n}\),定义其生成空间 \(V\)\(\forall (a_1,a_2,\dots,a_n)\neq (0,0,\dots,0)\)\((\sum a_i\vec{v_i})\in V\)。可以看出,\(V\) 是一个向量空间。

  6. 基:对于一个向量空间 \(V\),若能找出若干个向量,使它们的生成空间等于 \(V\),称这些向量为 \(V\) 的一组基。基可能不唯一。

    定理:不论怎么找基,基中向量个数都等于 \(V\) 中向量的维度。

  7. 奇排列和偶排列:对于排列 \(p\),记其逆序对个数为 \(inv(p)\)。如果 \(inv(p)\) 为奇数,称为奇排列;否则称为偶排列。

  8. 矩阵的转置。对于一个 \(n\times m\) 的矩阵 \(E\),定义其转置矩阵 \(E^T\)\(E^T\)\(m\times n\) 的矩阵,\(E^T_{i,j}=E_{j,i}\)

【矩阵乘法】

【向量】

向量:一个有方向的量。

如果没有方向,称为 “标量”;有方向,就是 “向量”。

平面向量:就是 \(2\) 维向量。

维度:如果一个向量是 \(n\) 维的,说明它可以用 \(n\) 个数确定方向

例如 \(2\) 维向量。

\(2\) 维向量,我们在 \(2\) 维平面上研究。因为我们不在乎起点和终点,所以我们可以把起点平移到原点。

此时,终点落在平面上的一个点 \((a_1,a_2)\) 上,这就是向量的坐标。

同理,在 \(3\) 维向量中,我们可以用 \((a_1,a_2,a_3)\) 来表示终点所在的坐标。

所以,维度就是表示我们用多少个数就可以确定平面上的点

【矩阵的理解】

矩阵乘法,就是一个线性变换

什么叫线性变换

我们看一个函数:\(f(x)=kx\),这是一个一次函数,也就是线性的

类推:\(f(x_1,x_2,\cdots,x_n)=\displaystyle \sum_{i=1}^n k_ix_i\),也是线性的

这样我们通过 \((k_1,k_2,\cdots,k_n)\) 这个线性变换,把 \((x_1,x_2,\cdots,x_n)\) 变成了一个数。

观察矩阵乘法的运算法则:

\(c_{i,j}=\displaystyle \sum^k_{x=1}a_{i,x}\times b_{x,j}\),这不就是可以视为线性变换吗?

\(a_{i,x}\) 视作上面的 \(k_i\)\(b_{x,j}\) 视作上面的 \(x_i\)\(c_{i,j}\) 视作线性变换的结果。

再回过头看我们的矩阵乘法:

向量乘以矩阵,得出的向量就是经过线性变换后得出的向量

两个矩阵相乘,既可以视作很多个向量存在矩阵里,依次进行线性变换;也可以视为得出一个先做第一个变换,再做第二个变换的等价变换

oi-wiki

【用矩阵处理问题】

我们说到,矩阵可以视作一个线性变换

那么,如果我们的答案是一个经过若干次线性变换得出的,就可以考虑编成一个矩阵,然后利用快速幂\(\log\) 级别的时间内求出来。

例题:斐波那契数列,这题可谓相当经典。

我们看这个递推式:\(F_i=F_{i-2}+F_{i-1}\),满足 \(y=k_1x_1+k_2x_2\) 的形式,\(F_{i-2}\rightarrow x_1,F_{i-1}\rightarrow x_2\),这是线性变换!

所以我们可以考虑用矩阵乘法。

研究矩阵乘法的递推,我们从起点开始。

上面提到过,系数 \((k_1,\cdots,k_n)\) 是线性变换,那么 \(x_1,\cdots,x_n\) 就是起点。

所以把 \(x_1,x_2\) 存进矩阵当起点:

\[ mar = \begin{pmatrix} F_{i-2}&F_{i-1} \end{pmatrix} \]

我们往后推一步:

\[ mar^{*} = \begin{pmatrix} F_{i-1}&F_{i} \end{pmatrix} \]

\(mar\cdot\) 变换矩阵\(\,change\) \(=mar^{*}\)

\(mar^{*}_{\;\;1,1}=F_{i-1}\) 正好就是 \(mar_{2,1}\),根据矩阵乘法的定义,\(mar^*_{\;\;1,1}=mar_{1,1}change_{1,1}+mar_{1,2}change_{2,1}\)

我们只要恰好一个 \(mar_{2,1}\):所以\(change_{1,1}=0,change_{2,1}=1\)

同理得:\(change_{1,2}=change_{2,2}=1\)

所以:

\[\begin{pmatrix} F_{i-2}&F_{i-1} \end{pmatrix} \begin{pmatrix} 0&1\\ 1&1\\ \end{pmatrix} =\begin{pmatrix} F_{i-1}&F_i\\ \end{pmatrix} \]

\[\begin{pmatrix} F_{1}&F_{2} \end{pmatrix} \begin{pmatrix} 0&1\\ 1&1\\ \end{pmatrix}^{i-2} =\begin{pmatrix} F_{i-1}&F_i\\ \end{pmatrix} \]

同时,为了好写,我们可以把初始的一行矩阵也写成 \(2\times2\) 的方阵,第二行全是 \(0\) 即可。

【高斯消元】

高斯消元用来解决线性方程组的问题。

例如:

\[\begin{cases} 2x_1+3x_2+4x_3=20\\ x_1+2x_2+3x_3=14\\ 3x_1+x_2+2x_3=11 \end{cases} \]

得出 \(x_1=1,x_2=2,x_3=3\)

这就是线性方程组。

高斯消元法给出了一个普遍性的解决这种问题的方法。

假设我们要解决一个 \(n\) 元的线性方程组,第 \(i\) 个方程是 \(k_{i,1}x_1+k_{i,2}x_2+k_{i,3}x_3+\cdots+k_{i,n}x_n=a_i\)

我们建立一个 \(n\times (n+1)\) 的矩阵,其中矩阵的第 \(i\) 行为 \((k_{i,1},k_{i,2},\cdots,k_{i,n},a_i)\)

例如:

\[\begin{pmatrix} 2&3&4&20\\ 1&2&3&14\\ 3&1&2&11 \end{pmatrix} \]

我们的目标是得出一个矩阵,这个矩阵左边的 \(n\times n\) 应该是一个单位矩阵。

例如:

\[\begin{pmatrix} 1&0&0&1\\ 0&1&0&2\\ 0&0&1&3\\ \end{pmatrix} \]

这样,第 \(n+1\) 列的所有数就是 \(\{x_i\}\) 的解了。

回到一开始的矩阵,我们考虑考虑怎么做。

我们希望最后第一行第一列的是 \(1\),其他行第一列的都是 \(0\)

所以我们先让第一行第一列变成 \(1\),也就是除一下:

\[\begin{pmatrix} 1&1.5&2&10\\ 1&2&3&14\\ 3&1&2&11 \end{pmatrix} \]

然后我们用第一行 “消” 掉其他行的 \(x_1\),这就是平时解方程的加减消元法。

\[\begin{pmatrix} 1&1.5&2&10\\ 0&0.5&1&4\\ 0&-3.5&-4&-19 \end{pmatrix} \]

然后到 \(x_2\),注意到当我们消完 \(x_1\) 的时候,对之后每一行的乘除都不会影响到第一列的系数了。

因此我们让第二行的第二列变成 \(1\)

\[\begin{pmatrix} 1&1.5&2&10\\ 0&1&2&8\\ 0&-3.5&-4&-19 \end{pmatrix} \]

这个时候再用第二行消去其他行的 \(x_2\)。因为第一列已经是 \(0\),所以第二行加减第一行也不会影响 \(x_1\) 的系数 \(1\)

\[\begin{pmatrix} 1&0&-1&-2\\ 0&1&2&8\\ 0&0&3&9 \end{pmatrix} \]

最后到 \(x_3\),一样的操作。

\[\begin{pmatrix} 1&0&0&1\\ 0&1&0&2\\ 0&0&1&3\\ \end{pmatrix} \]

这样我们就得出了解。

但是!还有情况!无解或者无穷多解怎么办?

考虑一个无解的情况:

\(x_1+x_2=1,2x_1+2x_2=3\)

\[\begin{pmatrix} 1&1&1\\ 2&2&3 \end{pmatrix} \]

消去 \(x_1\)

\[\begin{pmatrix} 1&1&1\\ 0&0&1 \end{pmatrix} \]

发现,这个时候的最后一行,前面都是 \(0\) 但是最后一列不是。

这表示 \(0\ne 0\),矛盾,所以无解。

因此,只要我们做完高斯消元,发现有一行前面都是 \(0\) 但最后不是 \(0\),说明无解。

再看看无穷多解。

\(x_1+x_2=1,2x_1+2x_2=2\)

\[\begin{pmatrix} 1&1&1\\ 2&2&2 \end{pmatrix} \]

消去。

\[\begin{pmatrix} 1&1&1\\ 0&0&0 \end{pmatrix} \]

这个时候最后一行全都是 \(0\),说明无穷多组解。


高斯消元总结:

  1. 构建矩阵。

  2. \(i\) 次操作,从 \(i\sim n\) 行中找出一个第 \(i\) 列非 \(0\) 的行,把这个行换到第 \(i\) 行的位置,用这个行消去其他行。

    注意:如果找不到非 \(0\) 的行,说明无穷多组解。

  3. 结束后判断有没有全 \(0\) 的行或者前面全 \(0\) 但最后不是 \(0\) 的行。

【行列式】

行列式定义在一个矩阵 \(M\) 上,记作 \(det(M)\)

\[det(M)=\sum_{p=\text{1~n的一个排列}}sgn(p)\cdot\prod_{i=1}^n M_{i,p_i} \]

其中 \(sgn(p)=\begin{cases}-1&p\text{是奇排列}\\1& p\text{是偶排列}\end{cases}\) ,也能看出来 \(sgn(p)=(-1)^{inv(p)}\)

行列式有一些性质。

  • 将矩阵的某一列乘以一个标量 \(a\) 加到另一列上,行列式不变。

  • 交换矩阵的两列,行列式符号取反。

  • 将某列整体乘以一个标量 \(a\),行列式也乘以 \(a\)

  • 由于矩阵是对称的,上面关于 "列" 的性质,对 "行" 也同样成立。

【求行列式】

怎么求一个矩阵的行列式?根据这三条性质,有一个 \(O(n^3)\) 的算法。

首先考虑一个下(上)三角矩阵:对角线下方的位置都是 \(0\)。可以发现,这个矩阵的行列式就等于对角线上的数的乘积。

根据性质 "某行加减另一行若干倍,行列式不变" 可以用类似高斯消元的方式把原来的矩阵等价到一个下三角矩阵。

同时,高斯消元法里面会有交换两行的操作。在求行列式的时候,累计交换两行的次数,判断奇偶性,最后再取反即可。

这里可以延伸出一个行列式的性质。

  • 如果矩阵存在一些列或行(列向量的集合),它们线性相关,则这个矩阵的行列式为 \(0\)

    证明:如果这个矩阵有一些列或行线性相关,则我们用上面的变换,使矩阵的某一行(列)全为 \(0\),显然可得行列式为 \(0\)

【柯西-宾内 公式】

Cauchy-Binet 公式可以把两矩阵相乘的行列式拆成两个矩阵分别的行列式。

\[det(A\cdot B)=\sum_{S\subseteq\{1,2,\dots,n\},|S|=m}det(A_S)\cdot det(B_S) \]

介绍一下上面式子里的元素。

\(A\) 是一个 \(m\times n\) 的矩阵,\(B\) 是一个 \(n\times m\) 的矩阵,且 \(m\le n\)

\(S\) 是一个 \(m\) 的大小的 \(\{1,2,\dots,n\}\) 的子集。

\(A_S\) 是从 \(A\) 的一个子矩阵:如果 \(S\) 中包含 \(i\),则 \(A_S\) 中包含 \(A\) 的第 \(i\) 列。这些列顺次排列得到 \(A_S\)

\(B_S\) 是从 \(B\) 的一个子矩阵:如果 \(S\) 中包含 \(i\),则 \(B_S\) 中包含 \(B\) 的第 \(i\) 行。这些行顺次排列得到 \(B_S\)

【矩阵树定理】

矩阵树定理能在 \(O(n^3)\) 的时间内求出任意图的生成树个数。

对于一张图 \(G\)(暂时只考虑简单图),构造一个矩阵 \(Q\)

  • \(Q\)\(n\times n\)

  • \(Q_{i,i}=deg_i\),即 \(i\) 点的度数。

  • \(Q_{i,j}|i\neq j=\begin{cases}-1&\text{i,j 之间有边}\\0&\text{i,j 之间没有边}\end{cases}\)

\(M_{11}\)\(Q\) 删去第一行第一列的矩阵,矩阵树定理表明 \(det(M_{11})\) 等于 \(G\) 的生成树个数。

证明

考虑构造一个 \(n\times m\) 的矩阵 \(E\)\(E\) 的每一列代表一条边。若第 \(i\) 条边是 \((u_i,v_i)\),则 \(E\) 的第 \(i\) 列中第 \(u_i\) 行设为 \(1\),第 \(v_i\) 行设为 \(-1\),其他行设为 \(0\)。(这里 \(u_i\) 行设为 \(1\)\(v_i\) 行设为 \(1\) 也可以,因为某一列整体乘 \(a\) 行列式不变)

可以发现,\(E\)\(i\) 行所有数的绝对值之和等于 \(i\) 的度数。

观察\(Q=E\cdot E^T\)

考虑 \(Q\) 的第 \(i\) 行第 \(i\) 列的元素,也就是 \(E\) 的第 \(i\) 行和 \(E^T\) 的第 \(i\) 列对应相乘后求和。而 \(E^T\) 的第 \(i\) 列就等于 \(E\) 的第 \(i\) 行。那 \(E\) 的第 \(i\) 行与自身相乘答案是多少?答案就是第 \(i\) 行中有多少个非 \(0\) 的元素,就等于 \(i\) 的度数。

对于 \(Q\) 的第 \(i\) 行第 \(j\neq i\) 列的元素,对应到 \(E\) 的第 \(i,j\) 行:当 \(i,j\) 之间没有边,\(E\) 的第 \(i,j\) 行的每一列都至少有一个 \(0\);如果有边,则有一列贡献了 \(-1\)

观察证毕。

\(F\)\(E\) 去掉第一行留下的矩阵,类似观察可以证得 \(M_{11}=F\cdot F^T\)

这两个矩阵都一样,行列式自然也一样。所以 \(det(M_{11})=det(F\cdot F^T)\)

运用柯西-宾内(Cauchy-Binet)公式:\(det(M_{11})=det(F\cdot F^T)=\displaystyle\sum_{S}det(F_S)\cdot det(F^T_S)\)

根据柯西宾内公式的定义,这里枚举的 \(S\) 应该是一个大小为 \(n-1\)\(1\sim m\) 的子集。(\(F\) 是一个 \((n-1)\times m\) 的矩阵)我们发现 \(S\) 其实在 \(F\) 中对应了一颗生成树。

同时注意 \(F^T_S\) 的定义是:抽出 \(F^T\)\(S\) 中的行,而 \(F^T\) 的行就等于 \(F\) 的列,所以 \(det(F_S)\cdot det(F^T_S)=det(F_S)^2\)

所以 \(det(M_{11})\) 此时已经转到了 \(\displaystyle\sum_{\text{S}}det(F_S)^2\),其中 \(S\) 是一个大小为 \(n-1\) 的边集。

接下来我们要证明:\(det(F_S)=\begin{cases}\pm 1& \text{S 是生成树}\\0&\text{S 不是生成树}\end{cases}\) 。显然有了这个结论就能推出矩阵树定理。

先证明 \(det(F_S)=0\iff\text{S 不是生成树}\)

由于 \(S\)\(n-1\) 大小的边集,而不是生成树。所以 \(S\) 肯定有一个环:\(p_1,p_2,\dots,p_k\)

取出这 \(k\) 列,我们发现它们线性相关。所以 \(det(F_S)=0\)

再证明 \(det(F_S)=\pm 1\iff\text{S 是生成树}\)。我们如果证明了,可以通过交换 \(F_S\) 的两列使得 \(F_S\) 是下三角矩阵且 \(S\) 的对角线全是 \(\pm 1\),也就证明了这个命题。

(这里严格证明不会…… 咕一下)

总之,我们证明了矩阵树定理。


这里再回顾一下矩阵树定理的原本内容:矩阵树定理表明 \(det(M_{11})\) 等于 \(G\) 的生成树个数。

【矩阵树定理的拓展】

矩阵树定理的问题主要有两个方向:改造问题,变成生成树计数相关的问题;或者改造矩阵树定理的矩阵 \(Q\)

  1. 非简单图的矩阵树定理。

    在构造 \(Q\) 的时候,\(Q_{i,j}|i\neq j\) 不再等于 \(-1\),而是等于 \(-(\text{i,j 之间的边数})\)

    发现这个改动实际上只影响了对于 \(Q=E\cdot E^T\) 的证明,而 \(E\) 的第 \(i,j\) 行的乘积,还是等于 \(-\text{i,j 之间的边数}\)

  2. 边带权的矩阵树定理。

    发现,矩阵树定理实际上是计算了 \(\displaystyle\sum_{T}\prod_{e\in T}1\),其中 \(T\) 是一颗生成树。

    如果给每条边带上权,怎么做?也就是求 \(\displaystyle\sum_{T}\prod_{e\in T}w_e\)

    回想我们矩阵树定理最重要的一步:\(det(F_S)=\begin{cases}\pm 1& \text{S 是生成树}\\0&\text{S 不是生成树}\end{cases}\) ,我们由此推出当 \(S\) 的生成树的时候,答案会贡献 \(1\)。具体的做法是证明可以构造一个等价的下三角矩阵。对角线的乘积为 \(\pm 1\),进而 \(det(F_S)^2=1\)

    现在我们想要让生成树贡献 \(\prod w_e\),也就是让 \(det(F_S)^2=\prod w_e\),也就是 \(det(F_S)=\pm\prod\sqrt{w_e}\),也就是我们要构造一个下三角矩阵,对角线上都是 \(\pm \sqrt{w_e}\)

    我们知道了 \(E\) 怎么构造(注意这里不是 \(Q\) 的构造):对于第 \(i\) 条边 \((u_i,v_i,w_i)\),让第 \(i\) 列的第 \(u_i,v_i\) 行分别等于 \(\pm\sqrt{w_i}\)

    但是我们要求的是 \(Q\),要求的是 \(M_{11}\) 啊?这里有两种办法:\(Q=E\cdot E^T\),和 \(M_{11}=F\cdot F^T\)

【矩阵树定理的相关题目】

重建

题意:每条边有 \(p_i\) 的概率是好的。求图中有且仅有一颗生成树上的边是好边的概率。\(n\le 50\)

这里就相当于求 \(\displaystyle\sum_{T}(\prod_{e\in T}p_e)\cdot(\prod_{e\not\in T}(1-p_e))\)

我们知道矩阵树定理可以求 \(\displaystyle\sum_{T}\prod_{e\in T}p_e\),但是后面那个怎么办?

\(\displaystyle\prod_{e\not\in T}(1-p_e)=\prod_{e\in G}(1-p_e)\div \prod_{e\in T}(1-p_e)\),显然前面那半截可以提出来。

所以 \(\text{原式}=\displaystyle\prod_{e\in G}(1-p_e)\sum_{T}\prod_{e\in T}\dfrac{p_e}{1-p_e}\)

\(w_e=\dfrac{p_e}{1-p_e}\),就变成我们熟悉的形式了。

CF917D:有 k 条黑边的生成树

题意:给定一张图,每条边为黑白色。求恰好有 \(k\) 条黑边的生成树个数。\(n\le 100\)

借助多项式的系数表示方案数。

考虑重新构造矩阵 \(E\)。(再复习一下,\(E\) 的第 \(i\) 列代表第 \(i\) 条边)

如果边 \(i\) 为黑边,令 \(E\) 的第 \(i\) 列的两个数为 \(\sqrt{x}\)\(-\sqrt{x}\);否则令它们为 \(\pm 1\)

可能这里会疑惑为什么一定要一正一负:这是为了保证当 \(S\) 不对应生成树的时候,\(det(F_S)=0\)——因为我们要保证环对应的边能线性相关。

为什么要这样做?\(x\) 又代表什么?

首先,\(x\) 是一个形式参数。我们把它放在这里,是因为我们一会要通过多项式运算求方案数。

注意 \((\pm\sqrt{x})^2=x\),所以 \(\displaystyle\sum_{T}\prod_{e\in T}w_e=\sum_{T}x^{\text{T 中黑边个数}}\)

于是只要我们求出 \(\displaystyle\sum_{T}\prod_{e\in T}w_e\) 的结果(注意这个结果是一个多项式)。其中 \(x^k\) 的系数就是 \(k\) 条黑边的方案数。

但是这还不够,因为在求 \(det(F\cdot F^T)\) 的时候,需要做多项式的运算,每一次复杂度都是 \(O(n\log n)\) 的。太慢了。

我们其实只关心最后每一项的系数。而且因为生成树黑边数量显然 \(\le n-1\),所以最后的多项式最多 \(n-1\) 次。所以可以使用拉格朗日插值公式,令 \(x\)\(n\) 个不同的值分别代入,可以求得最终多项式的系数。

posted @ 2024-03-16 09:57  FLY_lai  阅读(18)  评论(0编辑  收藏  举报