题意:求A^1+..A^n
关于矩阵乘法中等比矩阵的求法:
|A E|
|0 E|
其中的A为m阶矩阵,E是单位矩阵,0是零矩阵。
由等比矩阵的性质:
|A , 1| |A^n , 1+A^1+A^2+....+A^(n-1)|
|0 , 1| 的n次方等于|0, 1|
即右上四分之一的矩阵减去单位矩阵就是所求矩阵
#include<iostream>
#include<string>
#include<cstdio>
#include<cstring>
#include<queue>
#include<map>
#include<cmath>
#include<stack>
#include<set>
#include<vector>
#include<algorithm>
#define LL long long
#define inf 1<<30
using namespace std;
int MAXN;
int mod;
struct Matrix
{
int mat[65][65];
Matrix() {}
Matrix operator*(Matrix const &b)const
{
Matrix res;
memset(res.mat, 0, sizeof(res.mat));
for (int i = 1 ;i <=MAXN; i++)
for (int j = 1; j <= MAXN; j++)
for (int k = 1; k <=MAXN; k++)
res.mat[i][j] = (res.mat[i][j]+this->mat[i][k] * b.mat[k][j])%mod;
return res;
}
};
Matrix pow_mod(Matrix base, int n)
{
Matrix res;
memset(res.mat, 0, sizeof(res.mat));
for (int i = 1; i <=MAXN; i++)
res.mat[i][i] = 1;
while (n > 0)
{
if (n & 1) res = res*base;
base = base*base;
n >>= 1;
}
return res;
}
int main()
{
int n,k;
Matrix base;
while(~scanf("%d%d%d",&n,&k,&mod))
{
MAXN=n*2;
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
scanf("%d",&base.mat[i][j]);
for(int i=1;i<=n;i++)//Right Top
for(int j=n+1;j<=2*n;j++)
{
if(i+n==j) base.mat[i][j]=1;
else base.mat[i][j]=0;
}
for(int i=n+1;i<=2*n;i++)//left bottom
for(int j=1;j<=n;j++)
{
base.mat[i][j]=0;
}
for(int i=n+1;i<=2*n;i++)//Right bottom
for(int j=n+1;j<=2*n;j++)
{
if(i==j) base.mat[i][j]=1;
else base.mat[i][j]=0;
}
Matrix ans=pow_mod(base,k+1);
for(int i=1;i<=n;i++)
for(int j=n+1;j<=MAXN;j++)
{
if(i+n==j) ans.mat[i][j]--;
while(ans.mat[i][j]<0) ans.mat[i][j]+=mod;
}
for(int i=1;i<=n;i++)
{
for(int j=n+1;j<=MAXN;j++)
printf("%d%c",ans.mat[i][j],j==MAXN?'\n':' ');
}
}
}