7_22_E题 Power of Matrix
题意
给出一个矩阵,求他的前k次幂之和。
思路
倍增法
∑i=1nAi=(E+An2)⋅∑i=1n2Ai
持续分治下去即可
代码
mobu
#include <cstdio>
#include <cstring>
using namespace std;
const int maxn = 45;
const int mod = 10;
typedef long long ll;
struct Mat {
int maze[maxn][maxn];
Mat(){
memset(maze,0,sizeof maze);
}
};
int n;
Mat Mat_mul(const Mat& a, const Mat& b){
Mat res;
for(int i = 0; i < n; i++)
for(int j = 0; j < n; j++){
for(int k = 0; k < n; k++) {
res.maze[i][j] = (res.maze[i][j] + a.maze[i][k] * b.maze[k][j])%mod;
}
}
return res;
}
Mat Mat_add(const Mat& a, const Mat& b){
Mat res;
for(int i = 0 ; i < n ; i ++){
for(int j = 0 ; j < n ; j ++){
res.maze[i][j] = (a.maze[i][j] + b.maze[i][j])%mod;
}
}
return res;
}
Mat Mat_Qpow(Mat base,int k){
Mat res;
for(int i = 0 ; i < n ; i ++)
res.maze[i][i] = 1;
while(k){
if(k & 1) res = Mat_mul(res, base);
base = Mat_mul(base, base);
k >>= 1;
}
return res;
}
Mat dfs(Mat base,int k){
if(k == 1) return base;
Mat res;
for(int i = 0 ; i < n ; i ++) res.maze[i][i] = 1;
if(k == 0) return res;
res = Mat_mul(dfs(base,k>>1),Mat_add(res,Mat_Qpow(base,k>>1)));
if(k&1) res = Mat_add(res,Mat_Qpow(base,k));
return res;
}
int main(){
int k;
while(~scanf("%d %d", &n, &k),n){
Mat a;
for(int i = 0 ; i < n ; i ++)
for(int j = 0 ; j < n ; j ++){
scanf("%d",&a.maze[i][j]);
a.maze[i][j] %= mod;
}
a = dfs(a,k);
for(int i = 0 ; i < n ; i ++){
for(int j = 0 ; j < n ; j ++){
if(j) printf(" ");
printf("%d",a.maze[i][j]);
}
puts("");
}
puts("");
}
return 0;
}