题意:见题目。
http://poj.org/problem?id=3233
有一种很好的做法是构造这样一个矩阵
A A
0 1
然后这个矩阵自乘K次即可,也就是矩阵套矩阵
#include<cstdio>
#include<cstring>
const int MAX = 65;
int n,k,m,tn,mod;
struct Mat {
int mat[MAX][MAX];
Mat(){
memset(mat,0,sizeof(mat));
}
void init(){
for(int i=0;i<n;i++)
for(int j=0;j<n;j++)
mat[i][j]= i==j;
}
void print(){
printf("****************\n");
for(int i=0;i<n;i++)
for(int j=0;j<n;j++)
printf(j==n-1?"%d\n":"%d ",mat[i][j]);
printf("****************\n");
}
friend Mat operator *(Mat a,Mat b);
friend Mat operator +(Mat a,Mat b);
friend Mat operator ^(Mat a,int k);
}E,A;
int a[MAX][MAX];
Mat operator +(Mat a,Mat b)
{
Mat c;
for(int i=0;i<n;i++)
for(int j=0;j<n;j++)
{
c.mat[i][j]=(a.mat[i][j]+b.mat[i][j]);
if(c.mat[i][j] >= mod) c.mat[i][j]-=mod;
}
return c;
}
Mat operator *(Mat a,Mat b)
{
Mat ans;
for(int i=0;i<n;i++)
for(int j=0;j<n;j++)
for(int k=0;k<n;k++)
{
long long tmp=(long long)a.mat[i][k]*b.mat[k][j];
if(tmp>mod) tmp%=mod;
ans.mat[i][j]=ans.mat[i][j]+tmp;
if(ans.mat[i][j] >= mod) ans.mat[i][j] -= mod;
}
return ans;
}
Mat operator ^(Mat a,int k)
{
Mat ans=E;
while(k){
if(k&1) ans=ans*a;
a=a*a,k>>=1;
}
return ans;
}
void init()
{
E.init();
for(int i=0;i<tn;i++)
{
for(int j=0;j<tn;j++)
{
A.mat[i][j]=a[i][j];
A.mat[i][j+tn]=a[i][j];
}
}
for(int i=tn;i<n;i++)
{
for(int j=tn;j<n;j++)
{
if(i==j)A.mat[i][j]=1;
}
}
}
int main()
{
while(scanf("%d%d%d",&tn,&m,&mod)!=EOF)
{
for(int i = 0; i < tn ; i++ )
{
for( int j = 0; j < tn ; j++)
{
scanf("%d",&a[i][j]);
}
}
n=2*tn;
init();
Mat ans=A^(m);
long long sum=0;
for(int i=0;i<tn;i++)
{
for(int j=tn;j<n;j++)
{
printf(j==n-1?"%d\n":"%d ",ans.mat[i][j]);
}
}
}
return 0;
}