acwing-206. 石头游戏
考点
- 矩阵乘法
- 快速幂
题解
1 |
|
思路
单看题意其实是纯模拟t
次,然而t
的范围高达1e9
,如果执行线性模拟会超时;
整个题目只有加法操作和乘一个系数操作,考虑矩阵乘法+快速幂加速。
把n * m
的网格看作长度为n * m
的一维向量,定义1
行
(n * m + 1)
的状态矩阵F
,下标为0 ~ n * m
;
已知\(\forall i\in \left[ 1,n \right] ,j\in
\left[ 1,m
\right]\),网格原(i, j)
的点映射到F
的下标为num(i, j) = (i - 1) * m + j
,
令F[num(i, j)]
记录格子(i, j)
中石头的个数,其中F[0] = 1
。
设\(F_k\)表示k
秒之后的状态矩阵,根据题意,初始时有\(F_0=\left[ \begin{matrix} 1& 0& 0&
\cdots& 0\\ \end{matrix}
\right]\),除了0位置之外的所有点石头数均为0。
接下来考虑构造转移矩阵A
,矩阵行、列下标都是0 ~ n * m
假设有网格\(\left[ \begin{matrix} a_1&
a_2\\ a_3& a_4\\ \end{matrix}
\right]\),转换成状态矩阵变成$F_0=$,其中a0
作为新增的常数项位置,恒为1。
假设a1
加5,a2
、a3
、a4
均不动,那么有如下等式:
\[
\begin{cases}
a_1=5\times a_0+1\times a_1+0\times a_2+0\times a_3+0\times a_4\\
a_2=0\times a_0+0\times a_1+1\times a_2+0\times a_3+0\times a_4\\
a_3=0\times a_0+0\times a_1+0\times a_2+1\times a_3+0\times a_4\\
a_4=0\times a_0+0\times a_1+0\times a_2+0\times a_3+1\times a_4\\
\end{cases}
\]
这里就体现了常数项a0
的作用了,可以很方便地累加;得到转移矩阵如下:
\[
\left[ \begin{matrix}
1& 5& 0& 0& 0\\
0& 1& 0& 0& 0\\
0& 0& 1& 0& 0\\
0& 0& 0& 1& 0\\
0& 0& 0& 0& 1\\
\end{matrix} \right]
\] 假设a3
向上推,其余保持不变,有如下等式: \[
\begin{cases}
a_1=0\times a_0+1\times a_1+0\times a_2+1\times a_3+0\times a_4\\
a_2=0\times a_0+0\times a_1+1\times a_2+0\times a_3+0\times a_4\\
a_3=0\times a_0+0\times a_1+0\times a_2+1\times a_3+0\times a_4\\
a_4=0\times a_0+0\times a_1+0\times a_2+0\times a_3+1\times a_4\\
\end{cases}
\] 得到转移矩阵如下: \[
\left[ \begin{matrix}
1& 0& 0& 0& 0\\
0& 1& 0& 0& 0\\
0& 0& 1& 0& 0\\
0& 1& 0& 1& 0\\
0& 0& 0& 0& 1\\
\end{matrix} \right]
\]
由于1 - 6
之间的数字的最小公倍数是60,意味着最多60次幂的时候,所有的操作序列都会重新回到最开始的1次幂处。
根据快速幂的思路,可以把每60次幂作为一个循环节,预先打表出60次幂得到的转移矩阵sixty
;
一共是t
次幂,可以拆分成t= q * 60 + r
,对于sixty
的q
次幂,可以直接使用矩阵快速幂进行求解,
而r
小于60,直接暴力运算即可。
整理一下最终的转移矩阵构造规律:
- 若网格
(i, j)
第k
秒的操作字符为N
,且i > 1
,那么令A[num(i, j)][num(i - 1, j)] = 1
,其余方向类似 - 若网格
(i, j)
第k
秒的操作字符是一个数字x
,令A[0][num(i, j)] = x
,A[num(i, j)][num(i, j)] = 1
,表示格子里本来的格子不动,再拿x
块石头 - 令
A[0][0] = 1
- 其余部分置
0