1. 程式人生 > >【矩陣快速冪】HDU1575Tr A【模板】

【矩陣快速冪】HDU1575Tr A【模板】

題目連結:http://acm.hdu.edu.cn/showproblem.php?pid=1575

題目描述:

Problem Description 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
   
  
 

題目程式碼:

#include <iostream>
#include <bits/stdc++.h>
#define MOD 9973
#define N 15
using namespace std;
int n, k, t;
struct Matrix {
    int m[N][N];
    Matrix()
    {
        memset(m, 0, sizeof(m));
    }
};
Matrix mul(Matrix a, Matrix b)
{
    Matrix res;
    for(int i = 0; i < n; i++) {
        for(int j = 0; j < n; j++) {
            for(int k = 0; k < n; k++) {
                res.m[i][j] = (res.m[i][j] + a.m[i][k] * b.m[k][j]) % MOD;
            }
        }
    }
    return res;
}
Matrix solve(Matrix a, int k)
{
    Matrix r;
    for(int i = 0; i < n; i++) r.m[i][i] = 1;
    while(k) {
        if(k & 1) r = mul(r, a);
        k >>= 1;
        a = mul(a, a);
    }
    return r;
}
int main()
{
    Matrix a;
    cin.sync_with_stdio(false);
    cin >> t;
    while(t--) {
        cin >> n >> k;
        for(int i = 0; i < n; i++)
            for(int j = 0; j < n; j++)
                cin >> a.m[i][j];
        Matrix tmp = solve(a, k);
        int ans = 0;
        for(int i = 0; i < n; i++)
            ans = (ans + tmp.m[i][i]) % MOD;
        cout << ans << endl;
    }
    return 0;
}