首先我们来想一下计算A+A^2+A^3...+A^k。
如果A=2,k=6。那你怎么算
2+22+23+24+25+26 = ?= (2+22+23)*(1+23)
如果A=2,k=7。那你怎么算
2+22+23+24+25+26+27 = ?= (2+22+23)*(1+23)+27
so....同理:
当k是偶数,A+A^2+A^3...+A^k=(E+A^(k/2))*(A+A^2...+A^(k/2))。
当k是奇数,A+A^2+A^3...+A^k=(E+A^(k/2))*(A+A^2...+A^(k/2))+A^k。
#include<iostream>
#include<cstring>
#include<cstdio>
#include<cstdlib>
using namespace std;
#define MAXN 50
int n,K;
struct node
{
int mat[MAXN][MAXN];
};
node calcu(node x, node y)
{
node ret;
memset(ret.mat,,sizeof(ret.mat));
for (int i = ; i <= n ; i++)
for (int j = ; j <= n ; j++)
{
for (int k = ; k <= n ; k++)
ret.mat[i][j] = (ret.mat[i][j] + x.mat[i][k] * y.mat[k][j]) % ;
}
return ret;
}
node add(node x,node y)
{
node ret;
memset(ret.mat,,sizeof(ret.mat));
for (int i = ; i <= n ; i++)
for (int j = ; j <= n ; j++)
{
ret.mat[i][j] = x.mat[i][j] + y.mat[i][j];
ret.mat[i][j] %= ;
}
return ret;
}
node pow_mat(node x,int cnt)
{
node ret;
memset(ret.mat,,sizeof(ret.mat));
for (int i = ; i < MAXN ; i++) ret.mat[i][i] = ;
while (cnt)
{
if (cnt & ) ret = calcu(ret,x);
x = calcu(x,x);
cnt >>= ;
}
return ret;
}
node dfs(node cur, int k)
{
if (k == ) return cur;
node res = dfs(cur,k / );
node ans;
ans = add(res,calcu(res,pow_mat(cur,k / )));
if (k & ) ans = add(ans,pow_mat(cur,k));
return ans;
}
int main()
{
while (scanf("%d%d",&n,&K) != EOF)
{
if (n == ) break;
node ans;
for (int i = ; i <= n ; i++)
for (int j = ; j <= n ; j++) {scanf("%d",&ans.mat[i][j]); ans.mat[i][j] %= ;}
node ret = dfs(ans,K);
for (int i = ; i <= n ; i++)
{
printf("%d",ret.mat[i][]);
for (int j = ; j <= n ; j++)
printf(" %d",ret.mat[i][j]);
putchar('\n');
}
putchar('\n');
}
return ;
}