矩阵加速

算法相关

矩阵乘法

矩阵 \(A_{n \times m}\) 左乘矩阵 \(B_{m \times k}\) 得到矩阵 \(C_{n \times k}\),其中 \(C_{i, j} = \displaystyle \sum_{t = 1} ^ m A_{i, t} \times B_{t, j}\)。

单位矩阵

主对角线元素全为 \(1\),其余元素全为 \(0\)。

矩阵快速幂

对于一个方阵,其可以自乘,可以将其自乘多次的结果视为该方阵的幂。可以用二进制拆分快速幂做到只做 \(O(\log n)\) 次乘法。

广义矩阵乘法

原先的狭义矩阵乘法是定义在 \((+, \times)\) 运算下的。我们新定义 \((\oplus, \otimes)\) 运算,若 \(\oplus\) 满足交换律,\(\otimes\) 满足结合律,\(\otimes\) 对 \(\oplus\) 有分配律则其可以进行矩阵乘法。

严格的来说,矩阵乘法是定义在半环上的。

经典的 \((\min, +)\) 可以进行矩阵乘法。

矩阵加速

一般有转移矩阵和答案矩阵相乘。个人习惯于将答案矩阵用行向量表示,那么实际是由答案矩阵左乘转移矩阵的若干次幂。

例如斐波那契数列:\(f_i = f_{i - 1} + f_{i - 2}\)。

其答案矩阵为:

\[\begin{bmatrix} f_{i - 1} \quad f_{i - 2} \end{bmatrix} \]

则可以构造转移矩阵为:

\[\begin{bmatrix} 1 \quad 1 \\ 1 \quad 0 \end{bmatrix} \]

即:

\[\begin{bmatrix} f_n \quad f_{n - 1} \end{bmatrix} = \begin{bmatrix} f_1 \quad f_2 \end{bmatrix} \times \begin{bmatrix} 1 \quad 1 \\ 1 \quad 0 \end{bmatrix} ^ {n - 2} \]

B2105 矩阵乘法

模板。

P3390 【模板】矩阵快速幂

模板。

P1962 斐波那契数列

模板。

P1349 广义斐波那契数列

模板。

P1939 矩阵加速(数列)

模板。

P5343 【XR-1】分块

思路

设 \(dp_i\) 表示长度为 \(i\) 时的答案。则有转移:

\[dp_i = \sum_{x \in S} dp_{i - x} \]

由于 \(x_{max} \le 100\),可以考虑矩阵加速。

套路地,我们构造一个 \(100 \times 100\) 的转移矩阵 \(A\),对于每一行 \(i\),将 \(S\) 中出现的元素 \(x\),\(A_{i, x} \to 1\),矩阵的其余元素赋为 \(0\)。

P10502 Matrix Power Series

简要题意

给定方阵 \(A\) 和整数 \(k\),求:

\[\sum_{i = 1} ^ k A ^ i \]

思路

考虑分治,记 \(f(k) = \sum_{i = 1} ^ k A ^ i\),\(x = \lfloor \frac{k}{2} \rfloor\)。

  • \(2 \mid k\):

\[f(k) = f(x) + A ^ x f(x) \]

  • \(2 \nmid k\)

\[f(k) = f(x) + A ^ x f(x) + A ^ k \]

这样时间复杂度是形如 \(T(n) = T(\frac{n}{2}) + O(k ^ 3 \log n)\) 的,于是总时间复杂度 \(O(k ^ 3 \log ^ 2 n)\)。

P10503 233 Matrix

思路

重要转移:

\[a_{i, j} = 10 \times a_{i - 1, 1} + 3 + \sum_{k = 2} ^ j a_{i - 1, k} \]

于是直接把每一列的 \(a\) 放到答案向量里即可矩阵加速。

CSES 1723

模板。

P3758 [TJOI2017] 可乐

思路

可以新建一个点表示自爆,且该点只存在一条指向自己的出边。

P2151 [SDOI2009] HH 去散步

思路

将无向边拆成正反两条边,对于每一条边记录其可以走到的边集即可,需要排除掉该边的反向边。

P4159 [SCOI2009] 迷路

思路

拆点。

CSES 1724

模板。

P4910 帕秋莉的手环

简要题意

可以在一个环上黑白染色,要求不存在相邻白色的方案数。

思路

设 \(dp_{i, 0 / 1}\) 表示前 \(i\) 位且第 \(i\) 位染黑或白的方案数。

转移:

\[dp_{i, 0} = dp_{i - 1, 1} \]

\[dp_{i, 1} = dp_{i - 1, 0} + dp_{i - 1, 1} \]

对于环的限制,改变初始值即可。

P5303 [GXOI/GZOI2019] 逼死强迫症

简要题意

有一个 \(2 \times n\) 的网格,每次你可以对于其中的 \(1 \times 2\) 或 \(2 \times 1\) 恰好两个不相邻的 \(1 \times 1\) 的位置染色。问全部染色的方案。

思路

设计 \(dp_i\) 表示填满前 \(i\) 列时的答案,\(f_i\) 表示只用 \(1 \times 2\) 或 \(2 \times 1\) 填满前 \(i\) 列的答案。

\(f_i\) 是好转移的,若最后是填两个 \(1 \times 2\) 则从 \(f_{i - 2}\) 转移而来;否则是最后填一个 \(1 \times 2\),从 \(f_{i - 1}\) 转移来。则 \(f_i = f_{i - 1} + f_{i - 2}\)。

考虑 \(dp_i\) 的转移,若最后是填两个 \(1 \times 2\) 则从 \(dp_{i - 2}\) 转移而来;若最后填一个 \(1 \times 2\),从 \(dp_{i - 1}\) 转移来;否则是最后 \(2 \times 2\) 的区域填 \(1 \times 1\),由于要求 \(1 \times 1\) 不相邻,因此贡献 \(2 \times f_{i - 2}\)。则 \(dp_{i} = dp_{i - 1} + dp_{i - 2} + 2 \times f_{i - 2}\)

这样又可以十分方便的进行矩阵加速。

Div. 2 E. Xor-sequences

简要题意

给定序列 \(a\),长度为 \(k\) 的序列 \(x\) 被称作“异或序列”,当且仅当以下两个条件全部满足:

  • \(\forall i \in [1,k] : x_i \in [1, n] \cap \mathbb{Z}\);
  • \(\forall i \in [1,k) : 3 \mid \mathrm{popcount}(a_{x_i}\mathbin{\mathrm{xor}} a_{x_{i + 1}})\)。

求有多少个异或序列。

思路

记 \(dp_{i, j}\) 表示第 \(i\) 位填 \(a_j\) 的方案数,有转移:

\[dp_{i, j} = \sum_{3 \mid a_j \oplus a_k} dp_{i - 1, k} \]

这样可以矩阵加速。

P3216 [HNOI2011] 数学作业

简要题意

求 \(1 \sim n\) 拼接后的结果。

思路

设 \(dp_i\) 表示 \(1 \sim i\) 拼接后的结果。有转移:

\[dp_i = dp_{i - 1} \times 10 ^ {1 + len(i)} + i \]

其中 \(len(i)\) 表示 \(i\) 在十进制下的位数。所以我们只要根据 \(len(i)\) 分段矩阵加速即可。

posted @ 2026-09-28 10:03  endswitch  阅读(5)  评论(0)    收藏  举报