算法学习笔记(38): 矩阵

一切线性操作都可以归为矩阵乘法

--by SmallBasic

本文是拿来玩耍,而不是学习的!

矩阵的加法,要求两个矩阵大小相等,于是可以对位单点相加。

Ci,j=Ai,j+Bi,j

关于矩阵乘法,定义一个 n×c 的矩阵 A 和一个 c×m 的矩阵 B,其乘法 C=AB 可以表示为:

Ci,j=k=1cAi,k×Bk,j

最终得到一个 n×m 的矩阵。

用一个简单一点的话来说,Ci,j 表示的是 A 的第 i 行,B 的第 j 列,一一对应相乘后求和的结果。

我们可以考察两个运算的性质:

  • 加法的结合律,交换律,数乘的分配律。这基于加法满足这些性质,而矩阵只是将多个运算一起进行了。
  • 乘法的结合律,分配律。结合律我不会证明,分配律可以从定义出发。

(A+B)Ck=1c(Ai,k+Bi,k)×Ck,j=k=1cAi,k×Ck,j+k=1cBi,k×Ck,j=AC+BC

值得注意的是,矩乘运算一般情况下不满足交换律!

矩阵在 OI 的用处比较广,很多较为高级的东西都可以用它来解释,所以了解是必要的。


线性递推

矩阵可以快速的求出形如 Fi=j=1kcjFij 的递推式,例如斐波那契数列:Fi=Fi1+Fi2

利用矩阵乘法可以表示为:

(FiFi1)=(1110)(Fi1Fi2)

如果我们多递推几次,可以有:

(FiFi1)=(1110)i1(F1F0)

考虑到矩阵乘法满足结合律,那么我们就可以通过快速幂的方式在 O(23logn) 的复杂度内求出斐波那契的第 n 项了。

如果有一个序列满足 gn=gn1+gn2,初始 g0=a,g1=b,那么我们可以知道 gn=Fn1g1+Fn2g0

证明是不难的。由于存在:

(gngn1)=(1110)n1(ba)

(1110) 写为:(F1F0F00),那么自然的,(F1F0F00)(1110)=(F2F1F1F0),归纳一下,得出:(1110)n=(FnFn1Fn1Fn2),n>1

于是

(gngn1)=(Fn1Fn2Fn2Fn3)(g1g0)

也就是说 gn=Fn1g1+Fn2g0

发现我们在证明中并没有用到 g0,g1 是什么,所以这可以轻易的扩展到任意类斐波那契的数列上。

然而推广是困难的,当初始项 3 后,我并没有想到该如何推广可能是我太菜了 QwQ


回到正常的斐波那契数列,如果我们稍稍将 n1 拆解一下,我们可以得到一个好玩的结论。

(FnFn1)=(1110)k(1110)n1k(11)=(FkFk1Fk1Fk2)(Fnk1Fnk2Fnk2Fnk3)(11)

Fn 那一堆展开,得到

Fn=Fk(Fnk1+Fnk2)+Fk1(Fnk2+Fnk3)=FkFnk+Fk1Fnk1

于是我们就这么发现并且无需证明的得到了某个恒等式,而不是通过更简单的归纳证明。


如果我们遇到了这种问题:

  • 定义递推数列 F,维护一个序列 A,多次区间加 F,也就是对于区间 [l,r],令 Ai=Ai+Fil,询问最终的序列。

如果只有一个加法是简单的,我们在前 k 个位置累加一下 F 初始序列,在 l+k 开始加入一个初始向量 F[0,k)

每次向后一个,乘上一个转移矩阵,顺便累加到原序列即可,在 r+1 的位置,我们直接将维护的向量减去 F[0,k)Trlk+1 即可,如果是纯矩阵是 O(nk2) 的,但是容易优化到 O(nk)

我们考虑矩阵满足结合律,于是每一个修改加入和减去向量是不会相互影响的,所以我们可以直接优化到 O(nk+mk)


超级矩阵快速幂!

哈密尔顿–凯莱定理,这是本方法最重要的理论。

在任何交换环上实或复的方阵 A 都满足 p(λ)=det(λInA)

而哈密尔顿–凯莱断言,p(A)=O

具体来说,考虑方阵:(1234),其特征多项式为:p(λ)=|λ123λ4|=λ25λ2

根据哈密尔顿–凯莱定理,我们可以知道 A25A2I=OA2=5A+2I

于是对于一个高次的 Ak 我们可以如此不断的简化,变成只需要对于原矩阵进行数乘和加法即可,这是 O(n2) 的。

但是本方法的瓶颈并不是在于求答案,而是求出特征方程,以及预处理矩阵的过程,这是很难完成的。最终出来的特征多项式是与矩阵的大小线性相关的,也就意味着我们需要预处理 O(n) 次的矩阵乘法才可以做到 O(n2) 的计算,而预处理的代价太昂贵,所以本方法其实没有任何作用。


矩阵与邻接矩阵

你猜猜为什么叫邻接矩阵而不是邻接表?

邻接矩阵 Gi,j 可以看作走一条边从 ij 的方案数。

自然的,我们考虑其乘法:Gi,j2=kGi,j×Gk,j,惊奇的发现 G2 表示的是走两条边从 ij 的方案数!

于是自然的,推广出来,Gk 表示的是走 k 条边从 ij 的方案数!

我们继续玩,将矩阵乘法变为 (min,+),那么 Gi,j2=mink(Gi,k+Gk,j),如果我们将 Gi,j 看作 ij 的最短路径,那么不就是说 Gn 就是全源最短路了!(这可以 O(n3logn) 求欸,好优秀)

但是 floyd 不乐意了,咱拿着 DP 不用,用矩阵干嘛,于是利用类似的东西搞出来了 O(n3) 的做法。

在稀疏图上不如 Johnson 全源最短路,O(nm+nmlogm)

我们回到方案数上,看这么一个问题:求一个图的 k 元环数量。

k=2,3,4 都是极其简单好做的,很容易做到 O(n3) 以内,但是在 n5 后事情开始变得复杂。

我们回到 Gk 的定义,自然的联想到 Gi,ik 中一定包含了满足为环的东西,但是也有不是的,需要容斥掉。

k=5 时,发现可能为一个 2 元环和 3 元环构成,如果我们能够把二元环不计入其中,是否就意味着我们就不需要容斥了?

问题在于如何容斥,我们考虑矩阵递推,设 Mk 表示不计入二元环的长度为 k 的路径数,自然 M1=GG2 中显然包含二元环,我们只需要减去 D 即可,也就是 M2=G2D

然而 M3 可以从 M2G 转移过来,但是发现多了一些东西,就是类似于 abcb 的路径,这可以从 M1 减去走一次二元环转移过来。我们可能会直接减去 M1D,但是发现会多减了一些东西,具体来说,多减了 abab 的路径,也就是说这里的路径不应该包含走回去的路径,所以得出实际上的递推式:Mk=Mk1GMk2(DI),k>2

于是我们得到了 CF1662C European Trip 的优秀做法。

回到 k 元环上,当 k=6 时,我们去掉了二元环,但是算出来会多一点点东西,具体来说,多了形如 abcadea,也就是两个三元环拼起来的东西,而算这个东西是简单的,所以我们简单的得出了 k=6 时的答案。

如果继续考虑 k=7 时,我们就会多算 3+4 的情况,类似的容斥即可。

但是当 k8 后,事情逐渐变的复杂,因为我们会遇到更多的情况,例如 3+5,4+4,在更大的时候还可能遇到 4+5,3+3+4,3+5+7 等等情况,这讨论就会十分复杂度了。


完了,还有好多东西需要邻接矩阵。

经典的,矩阵树定理,DG 的任一代数余子式也就是 TeTw(e)

好神秘的东西,还有一个 [# LGV引理] 我不会……


矩阵与线段树

乱七八糟的标记,看着头痛。

于是有了 算法学习笔记(33): 矩阵乘法与线段树标记


矩阵与 FFT

不是,这确实能扯,有多少人知道矩阵与 # 算法学习笔记(17): 快速傅里叶变换(FFT) 有什么关系?

离散傅里叶变换可以利用矩阵表示为:

[h(ω0)h(ω1)h(ω2)h(ωn1)]=[111111wn1wn2wn3wnn11wn2wn2×2wn2×3wn2×(n1)1wn(n1)×2wn(n1)×3wn(n1)×2wn(n1)×(n1)][c0c1c2cn1]

快速傅里叶变换做的事情本质上就是优化这一个矩阵乘法!


矩阵与期望

很经典的应用有一个 # 算法学习笔记(23): 马尔可夫链中的期望问题

还有好多期望的问题都需要用到矩阵转移。

例如说 P4457 [BJOI2018] 治疗之雨 和矩阵强相关!

不过线性代数的东西也不少。


不知道还能扯啥了

咱就不扯了吧 QwQ

posted @   jeefy  阅读(70)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?
点击右上角即可分享
微信分享提示