Matrix Power Series
Time Limit: 3000MS | Memory Limit: 131072K | |
Total Submissions:11389 | Accepted: 4861 |
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 nnonnegative 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
思路:矩阵的快速幂,又由于k比较大,并且要求的和是一个等比的数列,所以求解的时候可以用二分的方法。
所谓二分,举例如下:
求S = 2^1 + 2^2 + 2^3 + 2^4 的和。记为:maxsum(4)
先求出 temp = maxsum(4/2); 再求出 b = 2^2;那么所要求的和就是 temp = add(temp, temp * b);
然后在递归地求解maxsum(4/2)。
上面是k是偶数的情况,同样地,如果k是奇数的时候,讨论一下就OK了。
快速幂求(a^b)%m复杂度是log2(b).
虽然是完书中的代码,然后自己敲的,但是竟然1A了……不科学……
1 #include <iostream> 2 #include <cstdio> 3 #include <cstdlib> 4 #include <cstring> 5 #include <cctype> 6 #include <stack> 7 #include <queue> 8 #include <cmath> 9 #include <algorithm> 10 using namespace std; 11 #define LL long long 12 #define lson l, m, rt<<1 13 #define rson m+1, r, rt<<1|1 14 typedef struct matrix{ 15 int a[33][33]; 16 }matrix; 17 matrix A, B, per; 18 int m, k, n; 19 void init(){ 20 scanf("%d%d%d", &n, &k, &m); 21 for (int i = 0; i < n; ++i){ 22 for (int j = 0; j < n; ++j){ 23 scanf("%d", &A.a[i][j]); 24 A.a[i][j] %= m; 25 per.a[i][j] = (i == j); 26 } 27 } 28 } 29 matrix add(matrix a, matrix b){ 30 matrix c; 31 for (int i = 0; i < n; ++i){ 32 for (int j = 0; j < n; ++j){ 33 c.a[i][j] = 0; c.a[i][j] = (a.a[i][j] + b.a[i][j]) % m; 34 } 35 } 36 return c; 37 } 38 matrix multi(matrix a, matrix b){ 39 matrix c; 40 for (int i = 0; i < n; ++i){ 41 for (int j = 0;j < n; ++j){ 42 c.a[i][j] = 0; 43 for (int k = 0; k < n; ++k){ 44 c.a[i][j] += (((a.a[i][k]%m) * (b.a[k][j]%m))%m); 45 } 46 } 47 } 48 return c; 49 } 50 matrix pow(int k){ 51 matrix ans = per, m = A; 52 while (k){ 53 if (k&1){ 54 ans = (multi(ans, m)); k--; 55 } 56 k >>= 1; m = multi(m, m); 57 } 58 return ans; 59 } 60 matrix maxsum(int k){ 61 if (k == 1) return A; 62 matrix temp = maxsum(k/2), b; 63 if (k&1){ 64 b = pow(k/2+1); temp = add(temp, multi(temp, b)); 65 temp = add(temp, b); 66 } 67 else{ 68 b = pow(k/2); temp = add(temp, multi(temp, b)); 69 } 70 return temp; 71 } 72 73 int main(void){ 74 #ifndef ONLINE_JUDGE 75 freopen("3233.in", "r", stdin); 76 #endif 77 init(); 78 matrix ans = maxsum(k); 79 int j, i; 80 for (i = 0; i < n; ++i){ 81 for (j = 0; j < n-1; ++j){ 82 printf("%d ", ans.a[i][j]); 83 } 84 printf("%d\n", ans.a[i][j]); 85 } 86 87 return 0; 88 }
注意,求快速幂的时候,先把ans赋值成单位矩阵。
有时间认真写一下快速幂的思想。
突然赶脚自己的代码写得很挫……