矩阵乘法 $ \tiny\text{Matrix Multiplication} $
可以用来解决值域大的问题。
矩阵乘法可以用来加速线性递推式。
由于可以使用矩阵快速幂,矩阵乘法可以将线性递推 $ O(n) $ 的时间复杂度优化至 $ O(\log n) $。所以对于此类题型,最重要的就是找到固定的线性递推式,列出转移矩阵。
注意:矩阵无乘法交换律。乘的时候要注意顺序。
$ \text{Examples:} $
P1962 斐波那契数列
和某个入门题很像,但值域扩大到了 $ [1, 2^{63}) $ ,当然不能暴力求解,考虑把 $ f_{n} $ 和 $ f_{n - 1} $ 当成向量写在一起:\(\begin{bmatrix} f_{n} \\ f_{n - 1} \end{bmatrix}\),然后找出使下列等式成立的转移矩阵 $ \textbf{A} $:
\[\begin{bmatrix} f_{n} \\ f_{n - 1} \end{bmatrix} = \textbf{A}\begin{bmatrix} f_{n - 1} \\ f_{n - 2} \end{bmatrix}
\]
容易得出:$ \textbf{A}$ \(= \begin{bmatrix} 1 & 1 \\\ 1 & 0\end{bmatrix}\)。那么,乘上 $ n - 2 $ 次 $ \textbf{A} $ 后就是这样的:
\[\begin{bmatrix} f_{n} \\ f_{n - 1} \end{bmatrix} = \textbf{A}^{n - 2}\begin{bmatrix} f_{2} \\ f_{1} \end{bmatrix}
\]
P1349 广义斐波那契数列
与上一题相同,类比得到:
\[\begin{bmatrix} a_{n} \\ a_{n - 1} \end{bmatrix} = \textbf{A}^{n - 2}\begin{bmatrix} a_{2} \\ a_{1} \end{bmatrix}
\]
\[\textbf{A} = \begin{bmatrix} p & q \\ 1 & 0 \end{bmatrix}
\]
P1939 矩阵加速
这题的递推式有些奇怪,但不影响我们推,所以考虑开一个四维向量,如下:
\[\begin{bmatrix} f_{x} \\ f_{x - 1} \\ f_{x - 2} \\ f_{x - 3} \end{bmatrix} = \textbf{A}^{x - 4}\begin{bmatrix} f_4 \\ f_3 \\ f_2 \\ f_1 \end{bmatrix}
\]
再将 $ f_x $ 代换成 $ f_{x - 1} + f_{x - 3} $,解出:
\[\textbf{A} = \begin{bmatrix} 1 & 0 & 1 & 0 \\ 1 & 0 & 0 & 0 \\ 0 & 1 & 0 & 0 \\ 0 & 0 & 1 & 0 \end{bmatrix}
\]
P2044 随机数生成器
线性递推式:$ X_{n + 1} = aX_n + c $。
\[\begin{bmatrix} X_n \\ c \end{bmatrix} = \textbf{A}\begin{bmatrix} X_{n - 1} \\ c \end{bmatrix}
\]
\[\textbf{A} = \begin{bmatrix} a & 1 \\ 0 & 1 \end{bmatrix}
\]
注意到这题模数非常大,达到了 $ 10^{18} $ 的大小,所以应该使用龟速乘。
双倍经验:CF678D Iterated Linear Function
小声bb:@QianXiquq这题似乎跟贪心没有关系。
转置矩阵 $ \tiny\text{Matrix Transpose} $
一个矩阵的转置矩阵就是把矩阵的行列互换,形象的表示一个 $ m $ 行 $ n $ 列矩阵 $ \textbf{A} $ 的转置矩阵,记为 $ \textbf{A}^T $:
\[\textbf{A} = \begin{bmatrix} a_{11} & a_{12} & \cdots & a_{1n} \\ a_{21} & a_{22} & \cdots & a_{2n} \\ \vdots & \vdots & \ddots & \vdots \\ a_{m1} & a_{m2} & \cdots & a_{mn} \end{bmatrix}
\]
\[\textbf{A}^T = \begin{bmatrix} a_{11} & a_{21} & \cdots & a_{m1} \\ a_{12} & a_{22} & \cdots & a_{m2} \\ \vdots & \vdots & \ddots & \vdots \\ a_{1n} & a_{2n} & \cdots & a_{mn} \end{bmatrix}
\]
转置矩阵的性质:行列式的值不变。
转置矩阵可以用于向量点积的计算:
两个向量的点乘就是一个向量乘另一个向量的转置矩阵。
\[\overrightarrow{\textbf{x}}_i \ \cdot \overrightarrow{\textbf{x}}_j = \overrightarrow{\textbf{x}}_i {}^T \ \overrightarrow{\textbf{x}}_j
\]
高斯消元 $ \tiny\text{Gaussian Elimination} $
相信每个人都见过和下列线性方程组类似的方程组:
\[\begin{cases}3x+5y+2z=4\\x+y=-4\\5x+5y-9z=45\end{cases}
\]
为了好看,我们把消失的未知数系数补 \(0\),无系数的写成 \(1\),然后写成下面的样子:
\[\begin{cases}3x+5y+2z=4\\1x+1y+0z=-4\\5x+5y-9z=45\end{cases}
\]
那么,我们可以把系数写在一个 \(3\times3\) 矩阵中,剩下两样写成向量:
\[\begin{bmatrix}3&5&2\\1&1&0\\5&5&-9\end{bmatrix}\begin{bmatrix}x\\y\\z\end{bmatrix}=\begin{bmatrix}4\\-4\\45\end{bmatrix}
\]
那么这个等式就足以表示这个方程组了。
还记得单位矩阵吗?就是那个除了对角线为 \(1\) 以外全为 \(0\) 的矩阵。由计算或观察得到,一个对应阶数的单位矩阵乘上一个向量等于向量自身:
\[\begin{bmatrix}1&\cdots&0\\\vdots&\ddots&\vdots\\0&\cdots&1\end{bmatrix}\begin{bmatrix}a_1\\\vdots\\a_n\end{bmatrix}=\begin{bmatrix}a_1\\\vdots\\a_n\end{bmatrix}
\]
那么,根据以上结果,我们可以将答案矩阵放在系数矩阵的右边,成为一个增广矩阵,然后,对这个矩阵模拟加减消元法,使除对角线以外的数字为 \(0\),再判断是否出现了 \(0x_i=0\) 或 \(0x_i\ne0\) 的情况,就可以解出方程组了。
行列式 $ \tiny\text{Determinant} $
在数学中,让我们计算的行列式一般只有 $ 2 $ 阶和 $ 3 $ 阶的,而数学中计算行列式的“对角线法则”也不适用于 $ 3 $ 阶以上的行列式,那么要怎么计算高阶行列式呢?参照使用增广矩阵与高斯消元解多元一次方程的过程。仅保留此 $ n $ 阶行列式的对角线,其他数均消为 $ 0 $ ,行列式的值就是对角线的乘积。