题意:给出矩阵A和整数k,求出S=A+A^2+A^3+……+A^k
思路:矩阵快速幂
错误:前面几次超时,因为取模的次数太多了,因为题目给出了矩阵元素的最大值,所以不用每次乘的时候都对每个数取模,
代码如下:
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
const int maxn=35;
int N,K,M;
struct Matrix{
int n;
int a[maxn][maxn];
void clear(){
n=0;
memset(a,0,sizeof(a));
}
Matrix operator +(const Matrix &b)const{
Matrix tmp;
tmp.n=n;
for(int i=0;i<n;++i){
for(int j=0;j<n;++j){
tmp.a[i][j]=(a[i][j]+b.a[i][j])%M;
}
}
return tmp;
}
Matrix operator * (const Matrix &b)const{
Matrix tmp;
tmp.clear();
tmp.n=n;
for(int i=0;i<n;++i){
for(int j=0;j<n;++j){
for(int k=0;k<n;++k){
tmp.a[i][j]+=(a[i][k])*(b.a[k][j]);
tmp.a[i][j]%=M;
}
}
}
return tmp;
}
/* Matrix print(){
for(int i=0;i<n;++i){
for(int j=0;j<n;++j){
cout<<a[i][j]<<' ';
}
cout<<endl;
}
}*/
};
Matrix A;
Matrix pow(int t){
Matrix tmp;
tmp.n=A.n;
for(int i=0;i<N;++i){
for(int j=0;j<N;++j){
if(i==j)
tmp.a[i][i]=1;
else tmp.a[i][j]=0;
}
}
Matrix sav=A;
while(t){
if(t&1){
tmp=tmp*sav;
}
t>>=1;
sav=sav*sav;
}
return tmp;
}
Matrix solve(int k){
if(k==1)return A;
if(k==0){
Matrix tmp;
for(int i=0;i<N;++i){
for(int j=0;j<N;++j){
if(i==j)tmp.a[i][i]=1;
else tmp.a[i][j]=0;
}
}
return tmp;
}
Matrix tmp=solve(k>>1);
if(k&1){
tmp=tmp+tmp*pow(k>>1);
tmp=tmp+pow(k);
}
else{
tmp=tmp+tmp*pow(k>>1);
}
return tmp;
}
int main(){
// freopen("data.txt","r",stdin);
scanf("%d%d%d",&N,&K,&M);
A.clear();
A.n=N;
for(int i=0;i<N;++i){
for(int j=0;j<N;++j){
scanf("%d",&A.a[i][j]);
}
}
Matrix ans=solve(K);
for(int i=0;i<N;++i){
for(int j=0;j<N-1;++j){
printf("%d ",ans.a[i][j]);
}
printf("%d\n",ans.a[i][N-1]);
}
return 0;
}