版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/lidengdengter/article/details/81612341
给定n*n的矩阵A和k,求 ,直接在矩阵快速幂模板上加个手写的add函数会超时,过程中有重复计算,使用二分法:
将式子转变成
即
如果n是奇数,答案还要加上。这题要注意格式说明,每行没有多余的空格!
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
typedef long long ll;
const ll mod=10;
//ll mod;
int N;
struct matrix{
ll x[45][45];
};
matrix add(matrix a,matrix b){
matrix tmp;
memset(tmp.x,0,sizeof(tmp.x));
for(int i=0;i<N;i++)
for(int j=0;j<N;j++){
tmp.x[i][j]=a.x[i][j]+b.x[i][j];
tmp.x[i][j]%=mod;
}
return tmp;
}
matrix multi(matrix a,matrix b){//矩阵相乘
matrix tmp;
memset(tmp.x,0,sizeof(tmp.x));
for(int i=0;i<N;i++)
for(int j=0;j<N;j++)
for(int k=0;k<N;k++){
tmp.x[i][j]+=a.x[i][k]*b.x[k][j];
tmp.x[i][j]%=mod;
}
return tmp;
}
matrix quick_multi(matrix a,ll k){//矩阵快速幂
matrix tmp=a;
k--;
while(k){
if(k&1)
tmp=multi(tmp,a);
a=multi(a,a);
k>>=1;
}
return tmp;
}
matrix quick_add(matrix a,int n){
if(n==1)
return a;
matrix tmp,ans;
tmp=quick_add(a,n/2);
ans=add(tmp,multi(tmp,quick_multi(a,n/2)));
if(n&1) ans=add(ans,quick_multi(a,n));
return ans;
}
int main(){
int n,k;
while(~scanf("%d%d",&n,&k),n){
N=n;
matrix st;
for(int i=0;i<n;i++)
for(int j=0;j<n;j++){
scanf("%d",&st.x[i][j]);
st.x[i][j]%=mod;
}
matrix ans;
memset(ans.x,0,sizeof(ans.x));
ans=quick_add(st,k);
for(int i=0;i<n;i++)
for(int j=0;j<n;j++)
printf("%d%c",ans.x[i][j],j==n-1?'\n':' ');
printf("\n");
}
return 0;
}