题目描述
给定一个n*n的矩阵,求该矩阵的k次幂,即P^k。
输入描述
第一行:两个整数
n
(
2
<
=
n
<
=
10
)
n(2<=n<=10)
n(2<=n<=10)、
k
(
1
<
=
k
<
=
5
)
k(1<=k<=5)
k(1<=k<=5),两个数字之间用一个空格隔开,含义如上所示。
接下来有n行,每行n个正整数,其中,第i行第j个整数表示矩阵中第i行第j列的矩阵元素Pij且
(
0
<
=
P
i
j
<
=
10
)
(0<=Pij<=10)
(0<=Pij<=10)。另外,数据保证最后结果不会超过10^8。
输出描述:
对于每组测试数据,输出其结果。格式为:
n行n列个整数,每行数之间用空格隔开,注意,每行最后一个数后面不应该有多余的空格。
示例1
输入
2 2
9 8
9 3
输出
153 96
108 81
Solution
矩阵快速幂模板改一下取模大小即可。
#include <iostream>
#include <cstdio>
#include <cstring>
const int maxn = 20; //矩阵最大行列数
using namespace std;
struct Mat
{
int mat[maxn][maxn]; //矩阵
int row, col; //矩阵行列数
};
Mat mod_mul(Mat a, Mat b, int p) //矩阵乘法
{
Mat ans;
ans.row = a.row;
ans.col = b.col;
memset(ans.mat, 0, sizeof(ans.mat));
for (int i = 0; i < ans.row; i++)
for (int j = 0; j < ans.col; j++)
for (int k = 0; k < a.col; k++)
{
ans.mat[i][j] += a.mat[i][k] * b.mat[k][j];
ans.mat[i][j] %= p;
}
return ans;
}
Mat mod_pow(Mat a, int k, int p) //矩阵快速幂
{
Mat ans;
ans.row = a.row;
ans.col = a.col;
for (int i = 0; i < a.row; i++)
for (int j = 0; j < a.col; j++)
ans.mat[i][j] = (i == j);
while (k)
{
if (k & 1)
ans = mod_mul(ans, a, p);
a = mod_mul(a, a, p);
k >>= 1;
}
return ans;
}
int main()
{
// freopen("in.txt", "r", stdin);
Mat m;
int n, k;
while (~scanf("%d%d", &n, &k))
{
for (int i = 0; i < n; i++)
for (int j = 0; j < n; j++)
scanf("%d", &m.mat[i][j]);
m.col = m.row = n;
Mat ans = mod_pow(m, k, 10e8);
for (int i = 0; i < n; i++)
{
for (int j = 0; j < n; j++)
{
if (j != 0)
printf(" ");
printf("%d", ans.mat[i][j]);
}
printf("\n");
}
}
return 0;
}