A为一个方阵,则Tr A表示A的迹(就是主对角线上各项的和),现要求Tr(A^k)%9973。
Input
数据的第一行是一个T,表示有T组数据。
每组数据的第一行有n(2 <= n <= 10)和k(2 <= k < 10^9)两个数据。接下来有n行,每行有n个数据,每个数据的范围是[0,9],表示方阵A的内容。
每组数据的第一行有n(2 <= n <= 10)和k(2 <= k < 10^9)两个数据。接下来有n行,每行有n个数据,每个数据的范围是[0,9],表示方阵A的内容。
Output
对应每组数据,输出Tr(A^k)%9973。
Sample Input
2 2 2 1 0 0 1 3 99999999 1 2 3 4 5 6 7 8 9
Sample Output
2 2686
矩阵运算,数学不好是硬伤---
思想还是快速幂,只不过把数字换成了矩阵,再然后就是矩阵运算了
两矩阵A,B相乘得到新矩阵C,C[i][j]等于所有A矩阵第i行第k列数字与矩阵B第k行第j列数字的乘积之和
最后求的矩阵的快速幂,再计算新矩阵的迹,即主对角线之和
#include<cstdio>
#include<iostream>
#include<cmath>
#include<cstring>
#include<string>
#include<algorithm>
#include<map>
#include<queue>
#include<vector>
#include<functional>
#define PI acos(-1.0)
#define INF 0x3f3f3f3f
#define CL(a, b) memset(a, b, sizeof(a))
using namespace std;
typedef long long LL;
const int maxn = 5e4+10;
const int MOD = 1e9+7;
struct matrix{
int pos[20][20];
};
matrix A, B;
int n, k;
matrix mul_matrix(matrix A, matrix B){
matrix C;
for(int i = 0; i < n; i++){
for(int j = 0; j < n; j++){
C.pos[i][j] = 0;
for(int k = 0; k < n; k++){
C.pos[i][j] = (C.pos[i][j] + A.pos[i][k]*B.pos[k][j]%9973) % 9973;
}
C.pos[i][j] %= 9973;
}
}
return C;
}
matrix quick_pow(matrix A, matrix B, int b){//把数字改为矩阵的快速幂
while(b){
if(b&1){
B = mul_matrix(B, A);
}
b >>= 1;
A = mul_matrix(A, A);
}
return B;
}
int main(){
int t, kcase = 1;
scanf("%d", &t);
while(t--){
scanf("%d%d", &n, &k);
for(int i = 0; i < n; i++){
for(int j = 0; j < n; j++){
scanf("%d", &A.pos[i][j]);
B.pos[i][j] = A.pos[i][j];
}
}
int ans = 0;
B = quick_pow(A, B, k-1);//B此时和A相等,要求A^k,即A^(k-1)*B,即A^(k-1)*A
for(int i = 0; i < n; i++) ans = (ans + B.pos[i][i]) % 9973;//主对角线之和
printf("%d\n", ans % 9973);
}
return 0;
}