类似于等比数列求和,用二分.
一开始取余符号多用了几次,直接TLE了==
n%2==0: F[n]=F[n/2] (1+a[n/2]);
n%2==1: F[n]=F[n-1]+a[n];
#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
int n,mod,k;
struct Matrix
{
int m[31][31];
}E,Z;
inline Matrix Mut(Matrix A,Matrix B)
{
Matrix ans;
for(int i=0;i<n;i++)
for(int j=0;j<n;j++)
{
ans.m[i][j]=0;
for(int k=0;k<n;k++)
{
ans.m[i][j]+=((A.m[i][k])*(B.m[k][j]));
ans.m[i][j]%=mod;
}
}
return ans;
}
inline Matrix Add(Matrix A,Matrix B)
{
Matrix ans;
for(int i=0;i<n;i++)
for(int j=0;j<n;j++)
ans.m[i][j]=(A.m[i][j]+B.m[i][j])%mod;
return ans;
}
inline Matrix Pow(Matrix A,int b)
{
Matrix t=A,ans=E;
while(b)
{
if(b%2) ans=Mut(ans,t);
b/=2;
t=Mut(t,t);
}
return ans;
}
inline Matrix solve(Matrix A,int b)
{
if(b==0) return E;
else if(b==1) return A;
else if(b==2) return Add(A,Mut(A,A));
else if(b%2==1) return Add(Pow(A,b),solve(A,b-1));
else if(b%2==0)
{
Matrix ans=solve(A,b/2);
Matrix C=Pow(A,b/2);
Matrix B=Mut(ans,C);
return Add(B,ans);
}
}
int main()
{
//freopen("in.txt","r",stdin);
scanf("%d%d%d",&n,&k,&mod);
{
for(int i=0;i<n;i++)
for(int j=0;j<n;j++)
E.m[i][j]=(i==j);
Matrix A;
for(int i=0;i<n;i++)
for(int j=0;j<n;j++)
scanf("%d",&A.m[i][j]),A.m[i][j]%=mod;
Matrix ans=solve(A,k);
for(int i=0;i<n;i++)
{
for(int j=0;j<n;j++)
{
if(j!=0)
printf(" ");
printf("%d",ans.m[i][j]%mod);
}
printf("\n");
}
}
return 0;
}