题意就是一个等比数列求和的意思,只不过每一项都是矩阵
这里需要进行一下转移矩阵的构造,形成一个递推累加的效果:
设 B = (A,I;0,I)
则B^(k + 1) = (A^(k + 1),I + A + A^2 + A^3 + … + A^k;0,I)
原题可解,代码如下
#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <cstdlib>
#include <string>
#include <vector>
#include <stack>
#include <set>
#include <map>
using namespace std;
const int MAXN = 80;
int n, k, m;
struct Matrix
{
__int64 a[MAXN][MAXN];
int r;//行数
int c;//列数
}org, ans;
void print()
{
for (int i = 0;i < n;i++)
{
for (int j = 0;j < n;j++)
{
if (j) cout << " ";
if (i != j) cout << ans.a[i][j + n];
else cout << (ans.a[i][j + n] - 1 < 0 ? m - 1 : ans.a[i][j + n] - 1);
}
cout << endl;
}
}
Matrix mul(Matrix mat1, Matrix mat2)
{
Matrix res;
res.c = mat2.c;
res.r = mat1.r;
memset(res.a, 0, sizeof(res.a));
for (int i = 0;i < mat1.r;i++)
{
for (int j = 0;j < mat2.c;j++)
{
for (int k = 0;k < mat1.c;k++)
{
res.a[i][j] += mat1.a[i][k] * mat2.a[k][j];
res.a[i][j] %= m;
}
res.a[i][j] %= m;
}
}
return res;
}
void fmp()
{
k++;
while (k)
{
if (k & 1) ans = mul(ans, org);
org = mul(org, org);
k >>= 1;
}
}
int main()
{
while(cin>>n>>k>>m)
{
int i, j;
memset(org.a, 0, sizeof(org.a));
memset(ans.a, 0, sizeof(ans.a));
for (i = 0;i<n;i++) {
for (j = 0;j<n;j++)
scanf("%d", &org.a[i][j]);
}
for (i = 0;i<n;i++) {
org.a[i + n][i + n] = org.a[i][i + n] = 1;
ans.a[i][i] = ans.a[i + n][i + n] = 1;
}
org.c = org.r = 2 * n;
ans.c = ans.r = 2 * n;
fmp();
print();
}
return 0;
}