Time Limit: 3000MS | Memory Limit: 131072K | |
Total Submissions: 16986 | Accepted: 7233 |
Description
Given a n × n matrix A and a positive integer k, find the sum S = A + A2 + A3 + … + Ak.
Input
The input contains exactly one test case. The first line of input contains three positive integers n (n ≤ 30), k (k ≤ 109) and m (m < 104). Then follow n lines each containing n nonnegative integers below 32,768, giving A’s elements in row-major order.
Output
Output the elements of S modulo m in the same way as A is given.
Sample Input
2 2 4 0 1 1 1
Sample Output
1 2 2 3
解题思路:
代码:
1 # include<iostream> 2 # include<cstdio> 3 # include<cstring> 4 using namespace std; 5 const int MAX = 32; 6 7 struct Matrix 8 { 9 int v[MAX][MAX]; 10 }; 11 int n, k, M; 12 13 Matrix mtAdd(Matrix A, Matrix B) // 求矩阵 A + B 14 { 15 int i, j; 16 Matrix C; 17 for(i = 0; i < n; i ++) 18 for(j = 0; j < n; j ++) 19 { 20 C.v[i][j] = (A.v[i][j] + B.v[i][j]) % M; 21 } 22 return C; 23 } 24 25 Matrix mtMul(Matrix A, Matrix B) // 求矩阵 A * B 26 { 27 int i, j, k; 28 Matrix C; 29 for(i = 0; i < n; i ++) 30 for(j = 0; j < n; j ++) 31 { 32 C.v[i][j] = 0; 33 for(k = 0; k < n; k ++) 34 { 35 C.v[i][j] = (A.v[i][k] * B.v[k][j] + C.v[i][j]) % M; 36 } 37 } 38 return C; 39 } 40 41 Matrix mtPow(Matrix A, int k) // 求矩阵 A ^ k 42 { 43 if(k == 0) { 44 memset(A.v, 0, sizeof(A.v)); 45 for(int i = 0; i < n; i ++) 46 { 47 A.v[i][i] = 1; 48 } 49 return A; 50 } 51 if(k == 1) return A; 52 Matrix C = mtPow(A, k / 2); 53 if(k % 2 == 0) { 54 return mtMul(C, C); 55 } else { 56 return mtMul(mtMul(C, C), A); 57 } 58 } 59 60 Matrix mtCal(Matrix A, int k) // 求S (k) = A + A2 + A3 + … + Ak 61 { 62 if(k == 1) return A; 63 Matrix B = mtPow(A, (k+1) / 2); 64 Matrix C = mtCal(A, k / 2); 65 if(k % 2 == 0) { 66 return mtMul(mtAdd(mtPow(A, 0), B), C); // 如S(6) = (1 + A^3) * S(3)。 67 } else { 68 return mtAdd(A, mtMul(mtAdd(A, B), C)); // 如S(7) = A + (A + A^4) * S(3) 69 } 70 } 71 72 int main(void) 73 { 74 int i, j; 75 Matrix A; 76 cin >> n >> k >> M; 77 for(i = 0; i < n; i ++) 78 for(j = 0; j < n; j ++) 79 { 80 scanf("%d",&A.v[i][j]); 81 } 82 A = mtCal(A, k); 83 for(i = 0; i < n; i ++) 84 { 85 for(j = 0; j < n; j ++) 86 { 87 cout << A.v[i][j] << ' '; 88 } 89 cout << endl; 90 } 91 return 0; 92 }