特征值和特征向量
特征值和特征向量
定义 \(n\times n\) 的矩阵 \(A\),非零 \(n\times 1\) 的列向量 \(v\),实数 \(\lambda\),若:
那么称 \(v\) 为 \(A\) 的特征向量,\(\lambda\) 为特征值。
求解特征值
将定义式子移项得到:
其中 \(E\) 为单位矩阵,那么又因为 \(v\) 为非零向量,可以得到 \((\lambda E-A)\) 不满秩,换句话说也就是:
那么行列式求值后得到的会是一个 \(n\) 次多项式,对应的 \(n\) 个根即为特征值,称这个多项式为矩阵 \(A\) 的特征多项式。
直接把 \(\lambda\) 看成未知数做多项式操作复杂度为 \(O(n^5)\),或者直接插值能做到 \(O(n^4)\),但是可以做到更好。
定义相似矩阵:
对于可逆矩阵 \(P\),\(B=PAP^{-1}\) ,则称 \(B\) 为 \(A\) 的相似矩阵。
定理:相似矩阵的特征多项式相同
其实相似矩阵的迹(主对角线上元素之和)以及矩阵的秩和原矩阵相同,但求解特征多项式只需行列式相同即可。
这启示我们可以将 \(A\) 利用类似初等行变换的手法去变成一个好算行列式矩阵(例如上三角矩阵) \(B\) 然后再算特征多项式。
考虑用初等矩阵消元(初等矩阵都可逆)
定义 \(P(j,i(k))\) 表示将 \(E\) 的第 \(i\) 行的 \(k\) 倍加到第 \(j\) 行上。
那么矩阵 \(P(j,i(k))\) 中只有矩阵主对角线的值为 \(1\),\((i,j)\) 为 \(k\),其他的元素均为 \(0\)。
那么矩阵 \(P(j,i(k))^{-1}\) 中只有矩阵主对角线的值为 \(1\),\((i,j)\) 为 \(-k\),其他的元素均为 \(0\),即 \(P(j,i(-k))\)。
假设对矩阵 \(A\) 的第 \(j\) 行加上 \(k\) 倍的第 \(i\) 行。
那么在在行消后,第 \(i\) 列要减去第 \(j\) 列的 \(k\) 倍。
交换两行的操作也可以用类似的手法得到,如果交换了第 \(i\) 行和第 \(j\) 行,那么在交换完成后,第 \(i\) 列和第 \(j\) 列也会交换。
其实也就是对原来高斯消元的每个操作多执行一次共轭操作。
手完几个矩阵后你会发现绝大多数时候并不能消成上三角矩阵(比如交换第 \(i\) 行和第 \(j\) 行时,第 \(i\) 列的值会被污染),退而求其次,你可以消成一个上海森堡矩阵 \(B\),即对于 \(\forall i>j+1,B_{i,j}=0\)
\(*\) 号代表空矩阵。
那么现在的问题变成了如何在快速求解上海森堡矩阵的特征多项式。
性质这么好,考虑对最后一列拉普拉斯展开行列式
假设最后一列选择的元素为 \(b_{i,n}\),那么对于所有大于 \(i\) 的行,唯一能选择的方案为 \(b_{j,j-1}\),那么对于小于 \(i\) 的行列,又是一个递归的子问题 。
设 \(g_i\) 表示只考虑前 \(i\) 行 \(i\) 列的行列式。
后面要去负号的原因在于每加一个数逆序对个数加一。
设 \(f_i(x)\) 表示只考虑前 \(i\) 行前 \(i\) 列的特征多项式。(注意到计算的是 \(\det(\lambda E-A)\)),那么 \(A\) 中的所有数要取反!
最后一列取值为 \(a_{i,i}\) 时需要特殊判一下,因为贡献不一样。
稍微再化简一下得到:
其实可以做到 \(O(n^2)\),但是没必要。
P7776 【模板】特征多项式
那么在 \(O(n^3)\) 求出了一个矩阵的特征多项式。
其实算特征多项式算的是 \(\det(\lambda E-A)\),那能否推广呢?
即能否在 \(O(n^3)\) 计算 \(\det(A+Bx)\) 呢?
其实是可以的,首先你注意到。
尝试用高斯消元 \(B\) 让 \(B\) 最终变成单位矩阵(这里不需要用那个共轭操作),然后就变成我们会的东西了,但是有可能 \(B\) 不满秩。
如果当前在第 \(i\) 行,如果当前找的到主元直接换过来消元,如果找不到就看能否交换两列使得得到主元,如果还是找不到那么说明 \(B\) 所在的行全为 \(0\)。
此时将这一行全部乘以 \(x\),那么最终多项式的系数也会向右平移一个单位,再用前 \(i-1\) 行确定的信息去消元第 \(i\) 行。
如果还找不到就重新再来一遍,每次乘以 \(x\) 的代价为 \(O(n^2)\) 如果重复了大于 \(n\) 次说明多项式系数全为 \(0\) (向右平移了大于 \(n\) 个单位),那直接退出即可。
那么用 \(O(n^3)\) 将 \(B\) 消元成了一个只有在主对角线上元素有值且每个值均非 \(0\)。那我们把每一行的系数全部提取出来,设他们的乘积为 \(w\),那么现在就变成了求 \(\det(A+xE)\)。
把 \(A\) 全部取反后就变成了特征多项式板子题。
唯一要修改的地方就是将 \(f_0(0)\) 的值从 \(1\) 变成 \(w\)。
复杂度还是 \(O(n^3)\)
还能扩展吗?比如说求 \(\det(A+Bx+Cx^2)\) ?貌似是可以的,但是很复杂,笔者暂未学习。(坑 ,但是插值是一定能做的,复杂度劣一些)
[ABC323G] Inversion of Tree
题目想要区分逆序边和顺序边,那直接将逆序边的权值设为 \(x\),顺序边的权值设为 \(1\),放到矩阵树上的矩阵中,去掉任意一行一列,求 \(\det(A+Bx)\) 的每一项系数即可。
口胡的 idea
给定一个无向图,求有多少种方案选择一些边使得最终形成恰好 \(k\) 棵树,即森林大小为 \(k\),对于 \(k=1\sim n\) 分别求解。
\(n\le 500\)
建一个虚点,又恰好 \(k\) 棵等价于所有恰好有 \(k\) 棵树的根跟虚点连边。
虚点跟其他每个点连一条权值为 \(x\) 的边,其他边正常连 \(1\) 的边,跑矩阵树即可。
特征分解(对角化)
在矩阵快速幂中,计算 \(A^k\),每一次乘法都是 \(O(n^3)\),这不免让人感到失落。
如果说矩阵是一个对角矩阵(只有主对角线有值的话),那么乘法的效率会大大提高。
如果能找到一个对角矩阵 \(PBP^{-1}=A\)
那么
\(PBP^{-1}=A\) 那么可以得到 \(AP=PB\)
设 \(B\) 主对对角线上的元素分别为 \(\lambda_1,\lambda_2,\cdots,\lambda_n\),\(P\) 分成 \(n\) 个列向量 \(v_1,v_2,\cdots v_n\),那么:
因为 \(P\) 可逆,所以 \(v_1,v_2,\cdots,v_n\) 非零。
这对应着特征值和特征向量。
又因为 \(v_1,v_2,\cdots v_n\) 线性无关,那么一个矩阵可对角化的条件是矩阵满秩。
那么矩阵对角化的方法是:
1.先找到 \(n\) 个特征值。
2.对于每一个特征值找对应的特征向量。
直接高斯消元可以求得 \(v\)。
将所有 \(v\) 竖着拼在依次一个矩阵 \(P\) 里,\(\lambda_i\) 依次填入对角矩阵 \(B\)。
然后就得出了:\(PBP^{-1}=A\)
但是除非题目有特殊性质,否则根本没用。
因为我需要对一个多项式求根,且还可能出现复数。
所以往往要用矩阵对角化的题目大概率是一个上三角/下三角矩阵。
Perpetual Subtraction
设 \(f_{k,i}\) 表示 \(k\) 次后 \(x=i\) 的概率。
设 \(f_{k,x}\) 看作列向量,那么:
矩阵对角化!
首先这是一个上三角矩阵,对应的 \(\lambda_i=\dfrac{1}{i}\)。
由于矩阵真的非常优美,考虑手摸特征向量。
把它转换成线性方程组的语言:
倒着推算 \(v_j\),首先注意到 \(\forall j>i,v_j=0\)
来到第 \(i\) 行的时候,化简后变成 \(v_i\times 0=0\)
注意到如果此时再将 \(v_i\) 设为 \(0\) 的话,那么算出的向量 \(v\) 就只能是零向量了。
此时按理说是可以设为任意非零的值的,但是设为 \(1\) 能让矩阵更加优美(最后特征向量形成的矩阵比较有规律)
再根据已知的值推剩下的值 \(v_j\) 即可。
解出来(过程略,可手推)
把所有拼在一起得到矩阵 \(P\):
还需要求出 \(P^{-1}\),此时可以使用暴力矩阵求逆然后观察规律。
实际上你仔细想想。
这个矩阵正好对应着二项式反演的系数矩阵!
上面的系数矩阵对应着 \(P\),那么它的逆也就对应着下面的矩阵,即矩阵 \(P^{-1}\) 中 \((i,j)\) 的值为 \(\binom{j}{i}\)。\(B\) 对应的对角矩阵第 \(i\) 行第 \(i\) 列为 \(\dfrac{1}{i}\),其余位置均为 \(0\)。
那么现在就变为求
下面简写 \(f_{0,i}\) 为 \(f_i\)
考虑计算 \(P^{-1}f_0\)
这就是差卷积的板子。
也是同样的套路,最后再成个对角矩阵就做完了。
Tasty Dishes
非常好的一道题,难道出题人真的来自外天空?太神了!
首先观察到随着时间增加 \(a_i\) 单调不降,如果 \(i\) 能从 \(j\) 转移而来当且仅当 \(a_j>0\),设 \(d_j\) 为恰好在第 \(d_j\) 天后大于第一次零。
因为 \(a_i\ge -i\) ,所以 \(a_j\) 一定会在 \(d_j+1\) 天大于零。那么:
考虑所有点对询问的贡献,设 \(A_{i,j}=j[j\to i]\),特别的,\(A_{i,i}=i\),\(e_i\) 为长度为 \(n\) 的列向量且恰好只有第 \(i\) 行的值为 \(1\)。
那么答案为:
后一坨是煎蛋的,直接暴力扫一遍即可。
左边还是困难的,主要问题在于 \(A\) 的矩阵大小太大了,做快速幂不能接受。
怎么办?还是考虑矩阵对角化!
\(A\) 矩阵是一个上三角矩阵,可以轻易地得到特征值 \(\lambda_i=i\)。
跟上一道题一样,找特征向量。
此题中的 \(A\) 并不是确定的,那就只能倒着消元得到 \(v_i\),过程跟上题类似,不展开。有趣的点在于可以将 \(v_{i,i}\) 设置成任意你喜欢的非零数。
现在将 \(A\) 化成了 \(PBP^{-1}\),直接带入式子,发现只能少个 log,没啥用。
仔细观察式子的内核,发现我们只在意矩阵的某一列的值而并非所有值。
考虑将每个 \(e_i\) 用 \(P[v_1,v_2,\cdots,v_n]\) 线性表示。
定睛一看,其实矩阵 \(c\) 就是 \(P^{-1}\) 的转置。化简左边的一坨:
已经明晰了许多,考虑把前面一坨拿进来。
前面两坨可以轻松的在 \(O(n)\) 的时间计算,只需考虑最后一坨。
考虑对每个 \(j\) 开一个树状数组,下标维护 \(k\) 维度,每次相当于单点修改前缀查询。
注意到单点修改时,如果修改前 \(a_i\le 0\) 修改后 \(a_i>0\),那整个的 \(d\) 数组需要重新计算,树状数组也要全部修改。
但是一共最多重构 \(n\) 次,所以复杂度不会爆炸。
复杂度 \(O(n^3\log n+qn\log n)\),可以将前面的 log 去掉(\(O(n)\) 建树状数组。)