矩阵快速幂
给定 n×n 的矩阵 A,求
。
第一行两个整数 n,k 接下来 n 行,每行 n 个整数,第 i 行的第 j 的数表示
。
输出
共 n 行,每行 n 个数,第 i 行第 j 个数表示
,每个元素对
取模。
输入 #1
2 1
1 1
1 1
输出 #1
1 1
1 1
【数据范围】 对于 100% 的数据:
先来了解一些矩阵相关的知识
矩阵(matrix)。n×m 的矩阵指的是n行,m列的矩阵。
如
就是指的 2×3的矩阵。
单位矩阵指的是 对角线上为1,其他位置为0的矩阵。
常用 I
来表示单位矩阵。
性质
矩阵满足结合律,所以在求矩阵的幂的时候,可以使用 矩阵快速幂加速。
分治的思路解决矩阵快速幂
node matrixPow(node a,ll k){//矩阵的幂次方
if(k==0){// 0次方
return I;//矩阵的0次方是单位矩阵
}
node t=matrixPow(a,k/2);//求 a^{n/2} 次方
if(k&1){//判断k是否是奇数
return matrixMins(matrixMins(t,t),a);
}else{//k是偶数
return matrixMins(t,t);
}
}
#include <iostream>
#include <cstdio>
using namespace std;
typedef long long ll;
const int N=105;
const int M=1e9+7;
struct node{
ll a[N][N]={0};
int row,col;
};
node I;//单位矩阵
node matrixMins(node a,node b){//矩阵乘法
node c;//答案矩阵
c.row=a.row;
c.col=b.col;
int n=c.row,p=c.col,m=a.col;
//计算矩阵乘法
for(int i=1;i<=n;i++){
for(int j=1;j<=p;j++){
for(int k=1;k<=m;k++){
c.a[i][j]+=a.a[i][k]*b.a[k][j]%M;
c.a[i][j]%=M;
}
}
}
return c;
}
node matrixPow(node a,ll k){//矩阵的幂次方
if(k==0){// 0次方
return I;//矩阵的0次方是单位矩阵
}
node t=matrixPow(a,k/2);//求 a^{n/2} 次方
if(k&1){//判断k是否是奇数
return matrixMins(matrixMins(t,t),a);
}else{//k是偶数
return matrixMins(t,t);
}
}
int main(){
int n;
node a;
ll k;
cin>>n>>k;
a.col=a.row=n;
I.col=I.row=n;
for(int i=1;i<=n;i++){//输入矩阵A
for(int j=1;j<=n;j++){
cin>>a.a[i][j];
//处理单元矩阵
if(i==j) I.a[i][j]=1;
else I.a[i][j]=0;
}
}
node ans=matrixPow(a,k);//计算a^k
//输出结果矩阵
for(int i=1;i<=ans.row;i++){
for(int j=1;j<=ans.col;j++){
cout<<ans.a[i][j]<<" ";
}
cout<<endl;
}
return 0;
}
Q.E.D.