矩阵加速学习笔记

矩阵加速

矩阵加速主要是把 DP 的转移写成矩阵的形式,然后用矩阵快速幂优化。

可以用矩阵快速幂优化要求矩阵的运算是满足有结合律的,常用的 \(\text{min,+}\) 卷积等。

还有一些特殊技巧,比如多组询问时可以预处理幂次的矩阵然后查询时直接用行向量来乘,以及存在矩阵光速幂。

P4223 期望逆序对

题意:给一个排列,求随机交换 \(k\) 次后的期望逆序对数。

思路:把期望乘上总方案数后就是对逆序对数计数,于是我们考虑每一对\((i,j)\)对最终答案的贡献。因为除了\((i,j)\)之外的位置都是等价的,因此相关的状态只有7种,转移可以写成一个矩阵,直接矩阵快速就可以了。

\[ \left|\begin{matrix} \tbinom{n-2}{2}&1&n-2&0&n-2&0&0\\ 1&\tbinom{n-2}{2}&0&n-2&0&n-2&0\\ 1&0&\tbinom{n-2}{2}+(n-3)&1&0&1&n-3\\ 0&1&1&\tbinom{n-2}{2}+(n-3)&1&0&n-3\\   1&0&0&1&\tbinom{n-2}{2}+(n-3)&1&n-3\\   0&1&1&0&1&\tbinom{n-2}{2}+(n-3)&n-3\\   0&0&1&1&1&1&\tbinom{n-2}{2}+2(n-4)+1\end{matrix}\right| \]

然后就是大分讨。

P4007 小 Y 和恐怖的奴隶主

题意:有一个只有 \(m\) 点生命值的“恐怖的奴隶主”,这个“恐怖的奴隶主”有一个特殊的技能:每当它被扣减生命值但没有死亡(死亡即生命值 \(\leq 0\)),且 Boss 的随从数量小于上限 \(k\),便会召唤一个新的具有 \(m\) 点生命值的“恐怖的奴隶主”。现在小 Y 可以进行 \(n\) 次攻击,每次攻击时,会从 Boss 以及 Boss 的所有随从中的等概率随机选择一个,并扣减 \(1\) 点生命值,她想知道进行 \(n\) 次攻击后扣减 Boss 的生命值点数的期望。

思路:设\(f[i][a][b][c]\)表示攻击\(i\)次后,有\(a,b,c\)个血量为\(1,2,3\)的随从的概率,那么有:

1.\(a\ne 0\)\(f[i+1][a-1][b][c]\leftarrow f[i][a][b][c]\times\dfrac{a}{a+b+c+1}\)

2.\(b\ne 0\)

\(a+b+c<k\)\(f[i+1][a+1][b-1][c+1]\leftarrow f[i][a][b][c]\times\dfrac{b}{a+b+c+1}\)

\(a+b+c\geqslant k\)\(f[i+1][a+1][b-1][c]\leftarrow f[i][a][b][c]\times\dfrac{b}{a+b+c+1}\)

3.\(c\ne 0\)

\(a+b+c<k\)\(f[i+1][a][b+1][c]\leftarrow f[i][a][b][c]\times\dfrac{c}{a+b+c+1}\)

\(a+b+c\geqslant k\)\(f[i+1][a][b+1][c-1]\leftarrow f[i][a][b][c]\times\dfrac{c}{a+b+c+1}\)

然后就可以快速幂了。但是这样是\(O(T166^3\log n)\)的,过不去,但是我们不需要求最后的整个矩阵,所以可以用一个行向量来乘,这样只需处理\(2^i\)的矩阵,复杂度是\(O(166^3\log n+T166^2\log n)\)

P6573 [BalticOI 2017] Toll

题意:有向图,给定 \(k\),有些满足 \(\left\lfloor\dfrac{a}{k}\right\rfloor+1=\left\lfloor\dfrac{b}{k}\right\rfloor\) 的点之间有边,多次询问两点最短路。

思路:一开始以为是双向边,感觉不可做,结果是单向边。

首先可以把所有点分成\(n/k\)块,然后只有相邻的块间有连边,于是可以用矩阵来维护块间的转移,再外面套上倍增,这样就可以了。

P4102 [HEOI2014] 林中路径

思路:没想到必须要维护 3 个矩阵。。。

维护 3 个矩阵,分别表示路径长度的 0,1,2 次方和。考虑倍增求 \(k\) 次幂,有:

\[\begin{aligned} A&=A+A\times G^m\\ B&=B+B\times G^m+mA\times G^m\\ C&=C+C\times G^m+2mB\times G^m+m^2A\times G^m \end{aligned}\]

P2012 拯救世界2

题意:有 12 种元素,其中有 4 种只能出现偶数次,4 种只能出现奇数次,求排列 \(n\) 个的方案数。

思路:究极矩阵快速幂优化。

首先是暴力的状压,用来压后 8 种的情况,然后分析出来其实值只与其中 1 的个数有关,于是状态就是 \(dp[i][0]\sim dp[i][8]\),同时因为 \(dp[i]\) 只和 \(dp[i-1]\) 有关,于是可以矩阵快速幂优化。

但是因为有多组询问,于是考虑矩阵光速幂,即每 65536 一组,这样最终只用 4 次。

因为我们要求的是转移矩阵乘上一个只有第一个元素是 1 的列向量,相当于就是矩阵中某一个固定的位置,于是可以就可以拆成 \(\sum\limits_{j=0}^8(\sum\limits_{i=0}^8(A_{4,i}B{i,j})\sum\limits_{k=0}^8C_{j,k}D_{k,0})\),于是最后就从 \(9^3\) 一次运算变成了 \(9^2\),然后就可以通过了。

P2106 Sam数

题意:求有多少个 \(k\) 位的数满足相邻两位的数字间差不超过 2。

思路:矩阵快速幂优化 DP。

其实不难,就是设 \(f[i][j]\) 表示第 \(i\) 位为 \(j\) 的方案数,发现转移 \(f[i][j]=\sum\limits_{|j-k|\le 2}f[i-1][k]\) 可以用矩阵刻画,于是直接矩阵快速幂即可。

P3702 [SDOI2017] 序列计数

题意:求有多少长为 \(n\) 的值域在 \([1,m]\) 的序列,满足和是 \(p\) 的倍数且至少有一个质数。

思路:首先,我们只关心一个数在模 \(p\) 意义下的值,那么先不考虑质数的限制,可以求出 \(1\sim m\) 中有多少模 \(p\)\(i\) 的数记作 \(cnt_i\),然后可以 DP,记 \(f[i][j]\) 表示选了 \(i\) 个数在模 \(p\)\(j\) 的方案数,我们发现转移显然是可以用矩阵优化的。

现在的问题就是怎么处理质数的情况。可以简单容斥,用所有数的情况减去只用非质数的情况,这样就可以解决了。

复杂度 \(O(p^3\log n+m)\)

P3193 [HNOI2008] GT考试

题意:求有多少个 \(n\) 位十进制数,满足给出的十进制字符串没有在这个数中出现过。

思路:设 \(f[i][j]\) 表示考虑前 \(i\) 位,已经匹配到了第 \(j\) 位的方案数,但是我们并不知道应该转移到哪里。这里就需要一个辅助数组 \(g[i][j]\) 表示如果当前匹配到了第 \(i\) 位,有添加数字的方法使得匹配到第 \(j\) 位,那么转移就是 \(f[i][j]=\sum f[i-1][k]\times g[k][j]\)

我们发现这就是矩阵乘法的形式,于是直接矩阵快速幂优化就可以了。\(g\) 的求法可以直接 kmp。

复杂度 \(O(m^3\log n)\)

posted @ 2024-02-14 11:47  Xttttr  阅读(19)  评论(0编辑  收藏  举报