【矩阵快速幂】【裸题】HDU1575 Tr A

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));
        }
    }
}

猜你喜欢

转载自blog.csdn.net/a617976080/article/details/88761647