题目
输入n*n的矩阵A,
求A的前1-k次幂矩阵和的矩阵S
输出S各元素%m
思路来源
挑战程序竞赛 P205
题解
构造一个左上角是A(输入矩阵),右上角是0(零矩阵)
左下角和右下角都是I(单位矩阵)的矩阵
然后根据,就可以求了
把构造的矩阵快速幂一下,
则=构造矩阵的k次幂的左下角矩阵*I
其实之前见过这个题……
这不是要做hdu2243么整理一下……
代码
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<map>
using namespace std;
typedef long long ll;
const int maxn=32;
int mod;
struct Matrix
{
ll a[65][65];
int r;
Matrix():r(64){
memset(a,0,sizeof a);
}
Matrix(int n):r(n)//考虑0次的单位矩阵
{
for(int i=0;i<n;++i)
{
for(int j=0;j<n;++j)
{
a[i][j]=0;
}
}
}
Matrix operator*(const Matrix &b)const
{
Matrix tmp(r);
for(int i=0;i<r;++i)
{
for(int j=0;j<r;++j)
{
for(int k=0;k<r;++k)
{
tmp.a[i][j]+=(a[i][k]*b.a[k][j])%mod;
if(tmp.a[i][j]>=mod)tmp.a[i][j]%=mod;
}
}
}
return tmp;
}
};
Matrix modpow(Matrix x,ll n)
{
Matrix p(x.r);
for(int i=0;i<p.r;++i)p.a[i][i]=1;
while(n)
{
if(n&1)p=p*x;
x=x*x,n/=2;
}
return p;
}
int n,m,k;
int a[maxn][maxn];
int main()
{
scanf("%d%d%d",&n,&k,&mod);
Matrix b(2*n);
for(int i=0;i<n;++i)
{
for(int j=0;j<n;++j)
{
scanf("%d",&a[i][j]);
b.a[i][j]=a[i][j];
}
b.a[n+i][i]=b.a[n+i][n+i]=1;
}
b=modpow(b,k+1);
for(int i=0;i<n;++i)
{
for(int j=0;j<n;++j)
{
int res=b.a[i+n][j]%mod;
if(i==j)res=(res-1+mod)%mod;
printf("%d%c",res,j==n-1?'\n':' ');
}
}
return 0;
}