poj 3233 Matrix Power Series ——矩阵快速幂+二分求解

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赋值成单位矩阵。

有时间认真写一下快速幂的思想。

突然赶脚自己的代码写得很挫……

原文地址:https://www.cnblogs.com/liuxueyang/p/2995871.html