hdu 1575 Tr 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

解題思路:題目描述的很清楚了,下邊我們就看如何實現。其實我們有了整數快速冪的基礎之後,矩陣快速冪就很好實現了。首先我們可以定義一個結構體,來表示矩陣(當然我們直接可以用二維數組來表示,但是因爲算快速冪時涉及到矩陣乘法,又返回值,而二維數組不可以作爲函數返回值,所以個人認爲結構體來保存比較方便)。這裏需要注意的是,我們要知道矩陣乘法的套路是什麼。
首先要知道只有在第一個矩陣的列數(column)和第二個矩陣的行數(row)相同時纔可以將兩個矩陣相乘。
矩陣乘法公式:這裏寫圖片描述
還有就是,我們在算整數快速冪是,初始值要賦值爲1,而矩陣快速冪的初始值就要賦值爲一個單位矩陣(就是除了主對角線上元素爲1外,其餘元素全部爲0)。

#include <bits/stdc++.h>
#define mod 9973

using namespace std;
struct Node
{
    int m[15][15];
}a,res,ans;
Node Mult( Node a,Node b,int n)///返回兩個矩陣相乘的結果
{
    Node temp;
    for(int i=1;i<=n;i++)
        for(int j=1;j<=n;j++)
            temp.m[i][j] = 0;
    for(int i=1;i<=n;i++)
        for(int j=1;j<=n;j++)
          for(int k=1;k<=n;k++)
            temp.m[i][j] = ((a.m[i][k]*b.m[k][j])%mod + temp.m[i][j])%mod;
    return temp;
}
void QuickPower(int n,int k)///算矩陣快速冪
{
    for(int i=1;i<=n;i++)///將ans初始化爲單位矩陣
       for(int j=1;j<=n;j++)
       if(i==j)ans.m[i][j] = 1;
       else ans.m[i][j] = 0;
    while(k){///利用整數快速冪的方法來算矩陣快速冪
        if(k&1)
            ans = Mult(ans,res,n);
        res = Mult(res,res,n);
        k>>=1;
    }
}
int main()
{
    int T;
    int n,k;
    scanf("%d",&T);
    while(T--){
        scanf("%d %d",&n,&k);
        for(int i=1;i<=n;i++){
            for(int j=1;j<=n;j++)
                scanf("%d",&res.m[i][j]);
        }
        QuickPower(n,k);
        int sum = 0;
        for(int i=1;i<=n;i++)///計算主對角線上的值
            sum = (sum + ans.m[i][i])%mod;
        cout<<sum<<endl;
    }
    return 0;
}
發佈了105 篇原創文章 · 獲贊 15 · 訪問量 3萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章