【笔记】矩阵

矩阵基础

定义:

数学意义上有更加严谨的矩阵定义,这里不过多展开,如有需要还请自行查询。

n×m个数排成nm列,第ij列的数记为ai,j。我们称这n×m个数为矩阵A的元素,记作:

A=[a1,1a1,2...a1,ma2,1......a2,m........................an,1......an,m]

两个或者两个以上的矩阵的行数和列数都相同,那么我们就说这两个或两个以上的矩阵是同型矩阵

当且仅当矩阵A和矩阵B为同型矩阵,且满足任意ai,j=bi,j时,我们称矩阵A等于矩阵B,记作A=B

基本运算

加法

只有两个同型矩阵才能相加。

AB为同型矩阵,A=a1,1,...,an,m,B=b1,1,...,bn,m

A+B=a1,1+b1,1,...ai,j+bi,j,...an,m+bn,m

例如:

[12534691113]+[01415131716191218]=[1+02+145+153+134+176+169+1911+1213+18]=[21620162122282331]

减法与加法同理。

乘法

矩阵与实数相乘:

定义矩阵A以及一个任意实数k,则Ak的乘积为:

[a1,1...a1,m.........an,1...an,m]×k=[a1,1×k...a1,m×k.........an,1×k...an,m×k]

再来看看矩阵之间的乘法

设矩阵AnA行,mA列,矩阵BnB行,mB列。

只有当mA=nB时,AB才能相乘。

矩阵之间的乘积依然是矩阵,我们AB的乘积为矩阵C。则矩阵CnA行,mB列。

Ci,j=ai,1×b1,j+ai,2×b2,j+...+ai,nA×bnA, j=r=1nAai,r×br,j

例如:

[123456]×[789101112]=[1×7+2×9+3×111×8+2×10+3×124×7+5×9+6×114×8+5×10+6×12]

矩阵也同样存在幂运算,一个矩阵的k次幂表示k个该矩阵相乘。

单位矩阵

在实数的运算中,我们规定1为实数的单位,1乘的任何实数的结果都为这个实数本身。

矩阵运算中,我们也有一个单位矩阵,单位矩阵乘任意矩阵的结果等于这个矩阵本身。

单位矩阵的主对角线值为1,其余位置都为0

一个3×3的单位矩阵:

[100010001]

例:

[100010001]×[x1x2x3]=[1×x1+0×x2+0×x30×x1+1×x2+0×x30×x1+0×x2+1×x3]=[x1x2x3]

零矩阵

一个矩阵中的所有元素都为0则称这个矩阵为零矩阵。

零矩阵与任意矩阵相加都等于这个矩阵本身,与任意矩阵相乘都等于零矩阵。(前提是这两个矩阵能够相加或相乘)

矩阵的性质

一、加法:

定义AB为同型矩阵。

加法交换律A+B=B+A

加法结合律(A+B)+C=A+(B+C)

A+O=A (O为零矩阵)

二、乘法

乘法结合律 :(AB)C=A(BC)

左分配律:A×(B+C)=A×B+A×C

右分配律:C×(A+B)=C×A+C×B

由于矩阵乘法需要满足前者的列数等于后者行数这一性质,相乘顺序对于矩阵乘法非常重要。

矩阵乘法不一定满足交换律。

实际应用

矩阵快速幂

与整数运算一样,矩阵也存在同样的幂运算,也同样可以使用快速幂,时间复杂度同样为O(log n)。不过由于矩阵运算的特殊性,矩阵的行数和列数越大,常数也会有所增大。

矩阵与DP

矩阵快速幂优化递推式

拿最简单的斐波那契数列为例,递推式为:

f[i1]+f[i]=f[i+1]

假设我们现在要求斐波那契数列的第n位,用正常递推方法做的话时间复杂度为O(n),当n较大时会超时。

假设这个递推式不是加法,而是乘法,最好是幂运算的形式,我们就可以使用快速幂实现O(log n)的快速求解。

可惜这是一个加法递推式,但矩阵可以解决这个问题。

我们考虑把递推式左边写成一个矩阵的形式:

[f[i1]f[i]]

再试着把递推式右边也写成矩阵

[f[i]f[i+1]]

我们利用矩阵乘法,使得上述矩阵乘以一个矩阵后得到递推式右边。我们设乘上的这个矩阵为转移矩阵,记作C

那么:

[f[i1]f[i]]×C=[f[i]f[i+1]]

我们反过来想,看看右边这个矩阵是怎么乘过来的。

[f[i]f[i+1]]=[f[i1]×0+f[i]×1f[i1]×1+f[i]×1]

根据矩阵乘法的定义,我们可以得到转移矩阵

C=[0111]

即:

[f[i1]f[i]]×[0111]=[f[i]f[i+1]]

同样的,我们也可以用f[i]f[i+1]的矩阵乘上C得到包含f[i+1]f[i+2]的矩阵。

换句话说,我们用f[i1]f[i]的矩阵乘上矩阵C的二次方后得到了包含f[i+1]f[i+2]的矩阵。

那么,只要我们用f[i1]f[i]的矩阵乘乘上矩阵Cn次方,就能得到包含f[i+n1]f[i+n]的矩阵。

由于我们知道斐波那契数列的前两位(也就是f[1]f[2]),那么我们可以将其作为初始矩阵。

再用矩阵快速幂算出转移矩阵Cn2次方,用初始矩阵乘上转移矩阵的n2次方,就能得到一个包含f[n1]f[n]的矩阵,也就求出了斐波那契数列的第n位。时间复杂度接近快速幂。

同样的,对于别的递推式,我们可以将已知的数作为初始矩阵,再根据递推式推导出转移矩阵,通过快速幂加快递推过程。

大部分DP都可以写成递推的形式,我们可以用矩阵加速递推式("矩阵能加速所有递推式"---Gym学长)

矩阵与动态DP

当一个DP问题需要支持修改操作的时候,一切都变得麻烦起来了。因为没一个修改对DP的影响我们都有可能需要从头再DP一遍,时间复杂度难以接受。

矩阵结合律以及不满足交换律这一特点给了它参与进动态DP的可能。

为什么呢?

首先矩阵是可以结合的,这使得我们我们可以直接维护矩阵,利用矩阵进行DP。

满足结合律,所以可以用快速幂加速。

不满足交换律,A×B 不一定等于B×A,这可以更好的满足DP需要的无后效性,方便转移。

广义矩阵乘法

为了更好的适应DP的需求,我们需要一个功能更强的矩阵乘法

我们规定表示两个满足如下规律的运算:

1. 满足交换律: ab=ba

2. 满足结合律: (ab)c=a(bc)

3. 满足分配率: a(bc)=ab+ac

如果这两个运算满足这些规律,那么:

A×B=1nAi,kBk,j

平时用的比较多的情况就是:

1. 是"+",是"×" (普通矩阵乘法)

2. maxmin,是"+"

第一种情况前文讲过了,我们再来看看第二种情况。

Ci,j=maxk=1nAi,k+Bk,j

实例

给出一个序列ai,规定一个区间的权值和为ai的和,要求你找到一个权值和最大的区间。

这是个很简单的问题,但是,你先别急。我们用广义矩阵做一下这个题。

我们设fi表示以i结尾的最大子段和,设ansi表示fi的前缀最大值,则:

fi=max(ai,fi1+ai)

ansi=max(ansi1,fi)=max(ansi1,fi1+ai,ai)

我们写成矩阵的形式,为方便转移多维护一个0

[aiINFaiai0aiINFINF0]×[fi1ansi10]=[max(ai,fi1)+max(INF,ansi1)+max(ai,0)max(ai,fi1)+max(0,ansi1)+max(ai,0)max(INF,0)+max(INF,0)+max(0,0)]

=[max(ai,fi1+ai)max(ansi1,fi1+ai,ai)0]=[fiansi0]

这样做有什么用吗?没用,但如果带上修改操作的话就有用了。

给出T次修改操作,每次修改这个序列中的一个值,并询问修改后的答案,正常的线性DP每次都要从头再DP一遍,太慢了。试试矩阵。

提起修改操作,我们不难联想到线段树之类的数据结构。还记得矩阵满足结合律吗?利用这一点我们可以选择用数据结构来维护矩阵。

每次单点操作影响的都是该位置上的矩阵,以及包含该位置区间的广义矩阵乘积,我们用线段树维护广义矩阵乘积每次修改仅更新从叶到根的logn个位置的对应区间。时间复杂度大约为O((n+m)logn),如果考虑矩阵乘法本身的计算的话还要再乘上33

对于一些树上DP,并且带修改操作的时候我们可以使用树剖+线段树,或者LCT实现全局平衡二叉树,维护矩阵。

插句题外话,动态DP这个猫坤在WC2018讲到的黑科技竟然在近几年的CSP和NOIP提高组中出现了两次,很怀疑他们是否有按照大纲出题。

更新ing,写的有点仓促,可能会有错误,还请指正。

posted @   int_Hello_world  阅读(43)  评论(7编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
点击右上角即可分享
微信分享提示