首先A^k我们可以通过快速幂求得,但是我们不能每一项都去算快速幂,这样还是会超时的。我们发现可以通过二分优化。
如果k为偶数,那么
(A+A2+....AK)=(A+...+Ak2)+Ak2∗(A+...+Ak2)
如果k为奇数,那么
(A+A2+....AK)=(A+...+Ak2)+Ak+12∗(A+...+Ak2)+Ak+12
因此我们可以递归求解
#include <cstdio>
#include <cstring>
#define N 32
#define ll long long
int n,mod,kk;
inline int read(){
int x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9') x=x*10+ch-'0',ch=getchar();
return x*f;
}
struct Matrix{
int mat[N][N];
Matrix(bool t){
memset(mat,0,sizeof(mat));
if(t) for(int i=1;i<=n;++i) mat[i][i]=1;
}
Matrix operator+(Matrix b){
Matrix res(0);
for(int i=1;i<=n;++i)
for(int j=1;j<=n;++j)
res.mat[i][j]=(mat[i][j]+b.mat[i][j])%mod;
return res;
}
Matrix operator*(Matrix b){
Matrix res(0);
for(int i=1;i<=n;++i)
for(int j=1;j<=n;++j)
for(int k=1;k<=n;++k)
res.mat[i][j]=(res.mat[i][j]+mat[i][k]*b.mat[k][j])%mod;
return res;
}
Matrix operator^(int k){
Matrix base(0),res(1);
memcpy(base.mat,mat,sizeof(mat));
for(;k;k>>=1,base=base*base)
if(k&1) res=res*base;
return res;
}
}a(0),ans(0),a1(0),a2(0);
Matrix solve(int k){
if(k==1) return a;
if(k&1){//k为奇数
a1=solve(k>>1);a2=a^(k+1>>1);
return a1*a2+a1+a2;
}
else{
a1=solve(k>>1);a2=a^(k>>1);
return a1*a2+a1;
}
}
int main(){
// freopen("a.in","r",stdin);
n=read();kk=read();mod=read();
for(int i=1;i<=n;++i)
for(int j=1;j<=n;++j) a.mat[i][j]=read();
ans=solve(kk);
for(int i=1;i<=n;++i){
for(int j=1;j<n;++j) printf("%d ",ans.mat[i][j]);
printf("%d\n",ans.mat[i][n]);
}
return 0;
}