题解:P10502 Matrix Power Series

· · 题解

Matrix Power Series 矩阵幂求和

写不来分治,只好慢慢推公式。

引理:两个矩阵相乘能分解为若干个矩阵相乘(如果能的话)。

即:

\begin{matrix} A B \end{matrix} \right]\times \left[ \begin{matrix} CD\\ EF \end{matrix} \right]= \left[ \begin{matrix} A\times C + B\times E & A\times D+B\times F \end{matrix} \right] $$, 其中 $ABCDEF$ 均为大小相等的**矩阵**。 ~~可以手算。~~ ## 本题思路 令 $F_n = [A_n,S_n]$ ,其中 $A_n$ 与 $S_n$ 均为题目含义。 $B$ 为 $2n\times2n$ 的矩阵。 列得: $$[A_n,S_n]\times B=[A_{n + 1}, S_{n + 1}]$$, 已知: $$A_{n+1} = A_n \times A$$, $$S_{n+1} = S_n + A_{n+1}$$, 推导可得: $$B =\left[ \begin{matrix} A&A\\ 0&E \end{matrix} \right] $$。 其中 $A$ 为题目所给, $E$ 为单位矩阵。 即: $$F_{n} = F_1\times B^{k-1}$$。 **快速幂**计算即可。 ## 代码 ```cpp #include <bits/stdc++.h> using namespace std; const int N = 80; long long n, k, m; long long a[N][N], b[N][N]; void mul1(long long c[][N], long long a[][N], long long b[][N]) { long long temp[N][N] = {0}; for(int i = 1; i <= n; i ++) { for(int j = 1; j <= 2 * n; j ++) { for(int k = 1; k <= 2 * n; k ++) { temp[i][k] = (temp[i][k] + a[i][j] * b[j][k] % m) % m; } } } memcpy(c, temp, sizeof temp); }//n * 2n的矩阵与2n * 2n的矩阵相乘 void mul2(long long c[][N], long long a[][N], long long b[][N]) { long long temp[N][N] = {0}; for(int i = 1; i <= 2 * n; i ++) { for(int j = 1; j <= 2 * n; j ++) { for(int k = 1; k <= 2 * n; k ++) { temp[i][k] = (temp[i][k] + a[i][j] * b[j][k] % m) % m; } } } memcpy(c, temp, sizeof temp); }//2n * 2n的矩阵与2n * 2n的矩阵相乘 int main() { cin >> n >> k >> m; for(int i = 1; i <= n; i ++) { for(int j = 1; j <= n; j ++) { cin >> a[i][j]; a[i][j + n] = a[i][j];//F1 = [A A] b[i][j] = b[i][j + n] = a[i][j]; b[i + n][i + n] = 1;//B = [A A } //0 E] } k --; while(k) { if (k & 1) mul1(a, a, b); k /= 2; mul2(b, b, b); }//矩阵快速幂 for(int i = 1; i <= n; i ++) { for(int j = 1; j <= n; j ++) { cout << (a[i][j + n] + m) % m << " ";//输出Fn的Sn } puts(""); } return 0; } ```