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的内容。
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
思路
标准的矩阵快速幂
代码
import java.util.Scanner;
public class HDU1575 {
private static int MOD = 9973;
// 方阵乘法
private static int[][] multiply(int[][] A, int[][] B, int N){
int[][] C = new int[N][N];
for(int i = 0; i < N; i++){
for(int j = 0; j < N; j++){
int sum = 0;
for(int k = 0; k < N; k++){
// 取mod防止溢出
sum += (A[i][k] * B[k][j]) % MOD;
}
// 取mod防止溢出
C[i][j] = sum % MOD;
}
}
return C;
}
private static long solve(int[][] A, int N, int k){
// 初始化R为单位矩阵
int[][] R = new int[N][N];
for(int i = 0; i < N; i++) R[i][i] = 1;
while (k > 0){
if(k % 2 == 1){
R = multiply(R, A, N);
}
A = multiply(A, A, N);
k /= 2;
}
// 求tr(R)
int r = 0;
for(int i = 0; i < N; i++) r += R[i][i];
// 最后记得再mod一下
return r % MOD;
}
public static void main(String[] args){
Scanner in = new Scanner(System.in);
int T = Integer.parseInt(in.nextLine());
while (T-- > 0){
int N = in.nextInt(), k = in.nextInt();
in.nextLine();
int[][] A = new int[N][N];
for(int i = 0; i < N; i++){
for(int j = 0; j < N; j++){
A[i][j] = in.nextInt();
}
in.nextLine();
}
System.out.println(solve(A, N, k));
}
}
}