Tr A - 杭電1575(矩陣快速冪模板)
阿新 • • 發佈:2018-12-28
題目連結: Tr A-杭電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
題意描述:
給你一個 n(1<n<11)階方陣,讓你計算出它的 k 次方(不用輸出),並且最後輸出它主對角線的所有元素之和。中間還有一個取模運算,意思是每次計算的值都要對 9973 進行取模,使它處於 0~9972 。
思想解析:
題目樣例中給了 99999999 次方,所以肯定不能直接去算,直接算肯定超時的,所以這就涉及到了快速冪的思想,可以這麼解釋:每個十進位制數都可以變換成二進位制,比如21
有關快速冪思想的,可以參考整數快速冪這個部落格,這裡面講的比較詳細。
#include <iostream> #include <cstring> #include <cstdio> using namespace std; struct Ride ///用結構體來存放矩陣比較方便 { int e[20][20]; }; int n; Ride ride(Ride a,Ride b) ///兩個矩陣相乘 { Ride c; memset(c.e,0,sizeof(c.e)); for(int i=1; i<=n; i++) for(int j=1; j<=n; j++) for(int k=1; k<=n; k++) c.e[i][j] = (c.e[i][j] + a.e[i][k] * b.e[k][j]) % 9973; return c; } int main() { Ride rec,ans; int t,k,sum; cin >> t; while(t--) { sum=0; scanf("%d %d",&n,&k); for(int i=1; i<=n; i++) for(int j=1; j<=n; j++) scanf("%d",&rec.e[i][j]); memset(ans.e,0,sizeof(ans.e));///將ans矩陣變成單位矩陣 for(int i=1; i<=n; i++) ans.e[i][i]=1; while(k) { if(k & 1) ///當k的最後一位是1時,ans*rec ans=ride(ans,rec); rec=ride(rec,rec);///每次迴圈 rec都要自乘 k >>= 1; ///k右移,相當於k/2 } // for(int i=1; i<=n; i++) ///輸出矩陣 // { // for(int j=1; j<=n; j++) // printf("%d ",ans.e[i][j]); // cout << endl; // } for(int i=1; i<=n; i++) ///計算對角線和 sum = (sum+ans.e[i][i]) % 9973; cout << sum % 9973 << endl; } return 0; }