线性代数学习笔记
前言
因为博主太菜了所以需要写笔记来加深理解。
感谢队爷 cly 对我的耐心指导。
Part 1 向量
Part 2 矩阵乘法
矩阵其实可以看成若干向量。
矩阵相乘的定义我就不讲了,这个不知道的自己百度一下。
关于这部分,引入一些奇怪的知识(说奇怪是因为我目前没有用到过):
-
可以行拆分和列拆分进行运算,实质也是分块矩阵。具体的,进行运算的两段左边进行行拆分,右边进行列拆分。
-
可以拆分成分块矩阵。(配合一些乱七八糟的东西能达到 \(\operatorname {O}(n^{\omega})\) 求行列式,当然我觉得现阶段没必要,也掌握不了)
第二种理解方式
hehezhou 给了我又一种理解矩阵乘法的方式。
矩阵中的元素 \(A_{i,j}\) 表示从点 \(i\) 到点 \(j\) 的方案数。
若是从这个角度的话就可以快速地理解一些东西了。
Part 3 矩阵转化
如何把一个矩阵转化成我想要的样子呢?
这里我不知道怎么写比较好的引子,就直接上正题了吧。
在讲这块之前,需要一些前置知识:
矩阵的初等变换
矩阵的初等变换有三种:
\(1.\) 交换某两行(注意对应到矩阵的乘法中,需要左乘初等变换矩阵,若右乘即为交换两列)。
\(2.\) 将某一行乘上一个非零实数 \(k\)。
\(3.\) 将某一行的 \(k\) 倍(向量内每个元素都变成原来的 \(k\) 倍的意思)加到另一行上。
那么应该如何实现这三种操作呢?
单位矩阵
单位矩阵是一个 只有主对角线上的元素为一,其它都为零 的 \(n\times n\) 的矩阵,拥有 任何矩阵乘上单位矩阵都是自身 的良好性质,可以类比为普通乘法中的 \(1\)。
初等矩阵
那么若是我们对单位矩阵进行上述的初等变换,然后再将我们想进行操作的矩阵乘上这个得到的东西,是否就可以得到我们想要的结果?
小编也很惊讶,但事实就是这样。
你可以从定义或者上面描述的乘法的角度去理解。
对单位矩阵进行一次初等变换得到的东西,称为初等矩阵。
你会发现这个东西妙得很,可以做高斯消元,因为高斯消元需要的操作无非也是这几种。
并且你会发现,需要的是左乘初等矩阵,因为右乘会对列进行操作。
若是一个矩阵可以进行若干次初等变换变成单位矩阵,那么便称之为是可逆的。
但是具体的代码实现里面,并不需要真正去构建这种矩阵来转换,更多的是用于一些推导和证明。因为如果真的要实现那三种变换,直接按照定义去实现就好了。
Part 4 矩阵的逆
定义一个矩阵 \(A\) 的逆 \(B\),满足 \(AB=BA=E\),其中 \(E\) 表示单位矩阵。
具体的求法,我们可以将 \(E\) 拆分为 \(A\) 和若干个初等矩阵的乘积:\(x_1 x_2 \cdots A\),也就是说,\(A\) 可经过若干次初等变换得到 \(E\)。对于上面那个等式,我们左右同时左乘上这若干个初等矩阵,就得到了 \(EB=x_1 x_2 \cdots E\),那么 \(B=x_1 x_2 \cdots E\)。
那么如果不满足那个拆分的 \(A\) 呢?答案是 \(A\) 无逆,这点在之后的行列式求值也可以相联系。
Part 5 高斯消元
这个我感觉没有什么特别好讲的,利用前面的初等变换,进行平时解方程组的操作,不断消去未知数。
这里引入一个 增广矩阵 的概念,具体的,将未知数系数表示成一个 系数矩阵 \(A\),常数项单独作为一个矩阵(也可以叫做向量)\(x\),那么 增广矩阵 \(B=(A|x)\),是这样一个表示形式。这个定义会在后面用到。
那么 \(B\) 也是一样可以通过一系列变换变成阶梯型矩阵的。
练习
矩阵求逆
高斯消元
Part 6 行列式
式子我就不写了,网上都有。
朴素地求行列式的复杂度是 \(\operatorname O(n!(n \log+n))\)(大概)
反正也不会真有人去暴力做这个东西。
利用行列式的一些性质来进行求解:
\(1.\) 交换某两行。行列式取负。
\(2.\) 将某一行乘上一个非零实数 \(k\)。行列式乘上 \(k\)。
\(3.\) 将某一行的 \(k\) 倍(向量内每个元素都变成原来的 \(k\) 倍的意思)加到另一行上。行列式不变。
\(4.\) 一个矩阵若是有逆,则其行列式为逆矩阵的逆元(若是取模意义下的话),否则行列式为 \(0\)。
那么就是一样去做高斯消元的过程求逆矩阵(当然实际并不用求出这个逆),然后对行列式进行计算。
这里的计算部分有一种很巧妙的写法:将 \(A\) 消成上三角矩阵以后,将对角线元素相乘即为答案。至于为什么,可以自己推导一下,很有意思的。
以及,在这个过程中,如果说当前求行列式的矩阵不可逆,那么必然会在若干步初等变换后,出现某个对角线上的元素为 \(0\) 的情况,那么显然矩阵的行列式为 \(0\)。
也就是说:矩阵有逆 \(\Leftrightarrow\) 矩阵行列式不为 \(0\)。反之也是成立的,这样可以使得行列式与矩阵求逆联系在一起。
最小生成树计数
rt,如何计算最小生成树的方案数呢?
构造一个基尔霍夫矩阵,然后求出去掉最后一行和最后一列以后的行列式。
注:基尔霍夫矩阵中 \(A_{i,i}\) 表示点 \(i\) 的度数,\(A_{i,j},i!=j\) 表示邻接矩阵中 \(A_{i,j}\) 的相反数。(连边数取反)
练习
模板题
小 Z 的房间:
这题因为是对非质数取模,所以需要进行辗转相除。辗转相除的原理导致其跑完一遍只能将其消成上三角矩阵。然后这个过程中行列式只会有正负的变化,那么所有的 \(1\) 操作对行列式的贡献在上三角矩阵中就已经可以直接相乘求得了。
本身是需要将其 \(\times \frac{1}{c}\),但因为最后还要倒过来,所以就直接乘 \(c\) 计算就好了。
同时提醒我们,因为行列式跑的是最小生成树的方案数,所以若是塞进去无用的点会导致方案数变为 \(0\)。
辗转相除不得往回消。
[SHOI2016]黑暗前的幻想乡
也可以算作是板题,不过套了个简单容斥。
[JSOI2008]最小生成树计数
如何证明:按边权排序分层后,相同权值的边选取可行的 \(k\) 条对后面的层无影响,也就是无后效性。若是正确,则可以应用乘法原理来计算方案数,因为层层之间实际上独立。
在 kruskal 执行的过程中,对于 \(x\) 条相同权值的边,从中选取 \(k\) 条边保证选取后图为森林,这样形成的所有联通块的内部信息(只考虑有哪些节点,连接方案无所谓)是相同的。
考虑反证法,若不相同,则一定存在一条当前权值的边连接某两个联通块,使得这两者合并。
双倍经验 (甚至连代码都不用改,省选直接放两年前原题可还行)
对于这种分层的需要注意:
-
初始跑一遍判是否有解。
-
需要将除本层以外应加入的边加入后再去做。
Part 7 矩阵的秩
简单来说,秩就是:矩阵内部的极大 线性独立 向量的数目,自然有行列之分。
线性独立的一些向量,如果删去了某一个,那么它就不能被剩下的向量给表示出来。
更严谨的定义可以去网络上搜索,这里不过于详细地介绍。因为实际用处不大
现阶段,你大概只需要知道:秩就是高消出来的阶梯形矩阵的主元个数。
定义 \(r(A)\) 表示矩阵 \(A\) 的秩。
练习
POJ1830 开关问题
按照每个开关的效果构造出对应的向量,将它们转化为若干线性无关的向量,然后根据题意判断即可。
线性方程组
这里就可以用到前面那个定义了。对于 \(B=(A|x)\),分讨一下(已经通过高消转成线性无关的若干向量):
-
无解的判断是 \(r(B)>r(A)\),也就是某向量属于 \(A\) 的部分都为 \(0\),属于 \(x\) 的却非零。
-
有解且 \(r(A)=n\),那么有唯一解。
-
有解且 \(r(A)<n\),那么有无穷多解。
Part 8 线性基
前置知识
线性基指的是能够用 向量集合中若干向量通过线性运算得到 表示出来的向量集合。
更公式化地,可以描述为:对于线性无关的 \(n\) 个向量 \(x_1,x_2\cdots x_n\),所有可以表示为 \(a_1x_1+a_2x_2+\cdots a_nx_n\) 的向量组成的集合,就是一个线性基。
高消不会改变线性基
线性基可以用若干个线性无关的向量来描述,而高消的过程,实质上就是将这些线性无关向量求出的过程。
关于代码实现
这里推荐一种阳间的写法:
LL val[53];
inline void insert(LL x){for(int i=50;i>=0;i--)if((x>>i)>0){if(!val[i]){val[i]=x;break;}x^=val[i];}return;}
是支持动态插入维护的线性基。
练习
模板题
通过高消得到的阶梯型矩阵,满足每个主元列上,除了主元以外其他元素都为 \(0\)。
根据这个性质,我们就可以贪心选取了。
CF388D
这道题考察大家对于线性基知识的掌握程度,然后用这些知识写出转移方程式。
\(\texttt{2020-11-06 扩展题练习}\)
纪念一下第一次在 VJ 上拿 Rank 1。
这里面的题目都还不错,除了毒瘤高精 E。
下面五道是我觉得非常妙的,可以从中学到不少技巧性的东西。比如说如何构建转移矩阵,以及矩阵和一些算法的经典组合运用。
禁忌
经典多合一。
杰杰的女性朋友
考验矩阵运算性质的运用。
Fibonacci Strings
两个套路结合起来的题。
Axel and Marston in Bitland
算是这之中比较简单的一道。
向量内积
其实和线性代数关系并不是非常大,是道妙妙乱搞。