矩阵乘法例题讲解
1.定长路径统计
给出一个\(n\)个点\(m\)条边的有向图,每次给出三个整数\(u,v,k\),求有多少条从\(u\)到\(v\)的路径长度为\(k\)(不一定为简单路径)
我们用邻接矩阵\(G\)存储这个图,\(G_{u,v}\)表示从\(u\)到\(v\)的边数
令\(F_k\)为长度为\(k\)的路径条数构成的矩阵,显然有:
我们将其看作是两个矩阵相乘:
那么显然有:
矩阵快速幂即可
2.定长路径统计*
给出一个\(n\)个点\(m\)条边的有向图,每次给出三个整数\(u,v,k\),求有多少条从\(u\)到\(v\)的路径长度小于等于\(k\)(不一定为简单路径)
我们把每个点加一条连向自己的边权为\(1\)的边,跑矩阵快速幂即可
3.「LibreOJ 6208」树上询问
给出一棵有\(n\)个节点的树,根节点为\(1\)号节点每个节点有两个值\(k,t\),初始均为\(0\)
每次进行如下\(3\)种操作之一:
\(1.\operatorname{Add}(x,d)\):将\(x\)到根节点路径上每个点的\(k_i\leftarrow k_i+d\)
\(2.\operatorname{Mul}(x,d)\):将\(x\)到根节点路径上每个点的\(t_i\leftarrow t_i+d\times k_i\)
\(3.\operatorname{Query}(x)\):求\(t_x\)
\(1\le n,m\le 10^5,-10\le d\le 10\)
直接树剖确实可以做,但是比较麻烦,我们用矩阵来刻画每个操作:
\(\operatorname{Add}\):
\(\operatorname{Mul}\):
然后树剖维护即可
4.[TJOI2019]甲苯先生的字符串
给出一个仅有小写字母字符串\(S_1\),求满足如下条件的字符串\(S_2\)有多少种:
\(1.S_2\)长度为\(n\)
\(2.S_2\)仅由小写字母构成
\(3.S_1\)中长度为\(2\)的任意连续子串在\(S_2\)中不能出现
\(1\le n\le 10^{15}\)
我们将小写字母映射为数字,即\(a=1,b=2\dots z=26\)
令\(dp_{i,j}\)为长度为\(i\)且当前字符为\(j\)的合法字符串数量,显然有:
我们预处理出后面那个东西,令它为\(w\),那么就有:
\(n\)很大,暴力\(dp\)会炸掉,发现上面的转移方程是矩阵乘法的形式,可以用矩阵优化:
原矩阵:
base矩阵:
5.[SHOI2013]超级跳马
现有一个 \(n\) 行 \(m\) 列的棋盘,一只马欲从棋盘的左上角跳到右下角。每一步它向右跳奇数列,且跳到本行或相邻行。跳跃期间,马不能离开棋盘。例如,当 \(n=3,m=10\) 时,下图是一种可行的跳法。
求总方案数。
\(1\le n\le 50,2\le m\le 10^9\)
设\(dp_{i,j}\)为跳到\((i,j)\)的方案数,显然当只往右跳\(1\)格时有:
考虑到如果能一次跳到\((i,j)\),那么肯定也可以一次跳到\((i,j-2)\),所以转移方程即为:
直接\(dp\)发现\(O(nm)\)的复杂度接受不了,考虑矩阵优化(以\(n=3\)为例):
原矩阵:
base矩阵:
注意到\(n\)非常小,故以上做法可以通过


浙公网安备 33010602011771号