题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1575
题目大意:给定一个n*n的方阵A,经过A^k计算后对角线和为多少?
解题思路:这不是赤裸裸的矩阵二分快速幂吗?是的,果断模拟快速幂乘,快速幂乘是对整数进行乘法计算,矩阵快速幂是对矩阵进行乘法运算,本质是一样的。
测试数据:
3
2 2
1 0
0 1
1 2 3
4 5 6
7 8 9
0 0 0
0 0 0
0 0 0
代码:
#include <stdio.h>
#include <string.h>
#define MAX 11
#define MOD 9973
int k,n,ans,arr[MAX][MAX];
struct Mat {
int mat[MAX][MAX],size;
Mat(int n) {
size = n;
memset(mat,0,sizeof(mat));
}
Mat(int arr[][MAX],int n) {
size = n;
for (int i = 0; i < size; ++i)
for (int j = 0; j < size; ++j)
mat[i][j] = arr[i][j];
}
friend Mat operator *(Mat a,Mat b);
friend Mat operator +(Mat a,Mat b);
friend Mat operator ^(Mat a,Mat b);
};
Mat operator *(Mat a,Mat b) {
Mat c(n);
for (int i = 0; i < a.size; ++i)
for (int j = 0; j < b.size; ++j)
for (int k = 0; k < c.size; ++k)
if (a.mat[i][k] && b.mat[k][j])
c.mat[i][j] = (c.mat[i][j] + a.mat[i][k] * b.mat[k][j]) % MOD;
return c;
}
Mat operator +(Mat a,Mat b) {
Mat c(n);
for (int i = 0; i < a.size; ++i)
for (int j = 0; j < b.size; ++j)
c.mat[i][j] = (a.mat[i][j] + b.mat[i][j]) % MOD;
return c;
}
Mat operator ^(Mat a,int k) {
Mat c(n);
for (int i = 0; i < c.size; ++i)
c.mat[i][i] = 1;
while (k) {
if (k & 1) c = c * a;
a = a * a,k >>= 1;
}
return c;
}
int main()
{
int i,j,t;
scanf("%d",&t);
while (t--) {
scanf("%d%d",&n,&k);
for (i = 0; i < n; ++i)
for (j = 0; j < n; ++j)
scanf("%d",&arr[i][j]);
Mat c(arr,n);
c = c ^ k;
for (ans = i = 0; i < n; ++i)
ans = (ans + c.mat[i][i]) % MOD;
printf("%d\n",ans);
}
}
本文ZeroClock原创,但可以转载,因为我们是兄弟。