POJ 3233 Matrix Power Series (矩阵乘法,分块矩阵)
提交: 27 解决: 6
[提交] [状态] [命题人:admin]
题目描述
Given a n × n matrix A and a positive integer k, find the sum S = A + A2 + A3 + … + Ak.
输入
The input contains exactly one test case. The first line of input contains three positive integers n (n ≤ 30), k (k ≤ 109) and m (m < 104). Then follow n lines each containing n nonnegative integers below 32,768, giving A’s elements in row-major order.
输出
Output the elements of S modulo m in the same way as A is given.
样例输入
2 2 4
0 1
1 1
样例输出
1 2
2 3
构造一个$2n*2n$的矩阵。
$
\left\{
\begin{matrix}
A & one \\
zero & one
\end{matrix}
\right\}
$ ,其中one为单位矩阵,zero为0矩阵, $
\left\{
\begin{matrix}
A & one \\
zero & one
\end{matrix}
\right\}^{k+1} = \left\{
\begin{matrix}
A^{k+1} & A^k+A^{k-1}+...+A+one \\
zero & one
\end{matrix}
\right\}
$ ,取右上角的矩阵然后减去一个单位矩阵就是所求结果
#include "bits/stdc++.h" using namespace std; typedef long long ll; typedef unsigned long long ull; int n; int mod; struct martix { ll a[100][100]; }; martix mul(martix a, martix b) { martix ret; for (int i = 1; i <= 2 * n; i++) { for (int j = 1; j <= 2 * n; j++) { ret.a[i][j] = 0; for (int k = 1; k <= 2 * n; k++) { ret.a[i][j] = (ret.a[i][j] + a.a[i][k] * b.a[k][j]) % mod; } } } return ret; } martix powmod(martix a, int b) { martix ret; memset(ret.a, 0, sizeof(ret.a)); for (int i = 0; i < 80; i++) ret.a[i][i] = 1; while (b) { if (b & 1)ret = mul(ret, a); a = mul(a, a); b >>= 1; } return ret; } int main() { //freopen("in.txt", "r", stdin); martix A, S; memset(A.a, 0, sizeof(A.a)); int k; cin >> n >> k >> mod; for (int i = 1; i <= n; i++) { for (int j = 1; j <= n; j++) { cin >> A.a[i][j]; } A.a[i][i + n] = 1; A.a[i + n][i + n] = 1; } S = powmod(A, k + 1); for (int i = 1; i <= n; i++) { int flag = 0; for (int j = 1; j <= n; j++) { if (i == j)S.a[i][j + n]--; if (flag) cout << " "; flag = 1; cout << (S.a[i][j + n] + mod) % mod; } cout << endl; } return 0; }