POJ3233Matrix Power Series(十大矩阵问题之三 + 二分+矩阵快速幂)

http://poj.org/problem?id=3233

Matrix Power Series
Time Limit: 3000MS   Memory Limit: 131072K
Total Submissions: 18658   Accepted: 7895

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

Source

POJ Monthly--2007.06.03, Huang, Jinsong
当n为奇数;假设 n = 7: A + A ^ 2 + A ^ 3 + A ^ 4 + A ^ 5 + A ^ 6 + A^7 = A + A ^ 2 + A ^ 3 + A ^ 3 * (A + A ^ 2 + A ^ 3) + A ^ 7
当n为偶数的时候就简单了
 1 #include <iostream>
 2 #include <cstring>
 3 #include <cstdio>
 4 #include <algorithm>
 5 
 6 using namespace std;
 7 int n,m,k;
 8 struct Mat
 9 {
10     int mat[35][35];
11 };
12 Mat operator* (Mat x, Mat y)
13 {
14     Mat c;
15     memset(c.mat, 0, sizeof(c.mat));
16     for(int t = 1; t <= n; t++)
17     {
18         for(int i = 1; i <= n; i++)
19         {
20             for(int j = 1; j <= n; j++)
21                 c.mat[i][j] = (c.mat[i][j] + x.mat[i][t] % m * (y.mat[t][j] % m) ) % m;
22         }
23     }
24     return c;
25 }
26 Mat operator^ (Mat x, int y)
27 {
28     Mat c;
29     for(int i = 1; i <= n; i++)
30         for(int j = 1; j <= n; j++)
31             c.mat[i][j] = (i == j);
32     while(y)
33     {
34         if(y & 1)
35             c = c * x;
36         x = x * x;
37         y >>= 1;
38     }
39     return c;
40 }
41 Mat operator + (Mat x, Mat y)
42 {
43     for(int i = 1; i <= n; i++)
44     {
45         for(int j = 1; j <= n; j++)
46             x.mat[i][j] = ( x.mat[i][j] % m + y.mat[i][j] % m ) % m;
47     }
48     return x;
49 }
50 Mat dfs(int t,Mat temp)
51 {
52     if(t == 1)
53         return temp;
54     int mid = t / 2;
55     Mat c = dfs(mid, temp);
56     if(t & 1)
57     {
58        c = c + (temp ^ mid ) * c;
59        return c + (temp ^ t); //第一次交没加括号,查了好长时间的错,惭愧惭愧,其实codeblock都waring了,弱
60     }
61     else
62         return c + (temp ^ mid) * c;
63 }
64 int main()
65 {
66 
67     scanf("%d%d%d", &n,&k,&m);
68     Mat a,c;
69     for(int i = 1; i <= n; i++)
70         for(int j = 1; j <= n; j++)
71             scanf("%d", &a.mat[i][j]);
72     c = dfs(k,a);
73     for(int i = 1; i <= n; i++)
74     {
75         for(int j = 1; j < n; j++)
76             printf("%d ", c.mat[i][j]);
77         printf("%d\n", c.mat[i][n]);
78     }
79     return 0;
80 }
View Code

 

posted @ 2015-12-25 23:11  zhaop  阅读(236)  评论(0编辑  收藏  举报