HDU1757

解题思路:分析需要不少时间,比较懒,直接把别人的分析贴在这里,

  然后贴上自己写的代码:

K相当之大。所以逐一递推的算法无法胜任。这时我们就不得不运用矩阵加速。首先来讲一下矩阵乘法:
若一矩阵的列数与另一矩阵的行数相等,则可定义这两个矩阵的乘积。如 A 是 m×n 矩阵和 B 是 n×p矩阵,它们是乘积 AB 是一个 m×p 矩阵,其中
(AB)[i, j] = A[i, 1] * B[1, j] + A[i, 2] * B[2, j] + ... + A[i, n] * B[n, j] 对所有 i 及 j。
此乘法有如下性质:
(AB)C = A(BC) 对所有 k×m 矩阵 A, m×n 矩阵 B 及 n×p 矩阵 C ("结合律").
(A + B)C = AC + BC 对所有 m×n 矩阵 A 及 B 和 n×k 矩阵 C ("分配律")。
C(A + B) = CA + CB 对所有 m×n 矩阵 A 及 B 和 k×m 矩阵 C ("分配律")。
要注意的是:可置换性不一定成立,即有矩阵 A 及 B 使得 AB ≠ BA。

下面我们研究一下这道题如何运用矩阵。

f(x) = a0 * f(x-1) + a1 * f(x-2) + a2 * f(x-3) + …… + a9 * f(x-10)
构造的矩阵是:

|0 1 0 ......... 0|    |f0|   |f1 |
|0 0 1 0 ....... 0|    |f1|   |f2 |
|................1| *  |..| = |...|
|a9 a8 .........a0|    |f9|   |f10|

*/

我们看到规律了,每次要到下次个A*B,以此类推则由A*A*A.......A*B;

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<algorithm>
 4 using namespace std;
 5 const int maxn = 15;
 6 int k, mod;
 7 
 8 struct MT{
 9     int m[maxn][maxn];
10 };
11 
12 MT Mul(MT a, MT b)
13 {
14     MT res;
15     memset(res.m, 0, sizeof(res.m));
16 
17     for(int i = 0; i < 10; i++)
18     {
19         for(int j = 0; j < 10; j++)
20         {
21             for(int k = 0; k < 10; k++)
22             {
23                 res.m[i][j] += a.m[i][k]*b.m[k][j] % mod;
24             }
25             res.m[i][j] %= mod;
26         }
27     }
28     return  res;
29 }
30 
31 MT Product(MT a, int k)
32 {
33     MT r;
34     memset(r.m, 0, sizeof(r.m));
35     for(int i = 0; i < 10; i++)
36     {
37         r.m[i][i] = 1;
38     }
39 
40     while(k)
41     {
42         if(k & 1) r = Mul(r, a);
43         k >>= 1;
44         a = Mul(a, a);
45     }
46 
47     return r;
48 }
49 
50 int main()
51 {
52     MT a;
53     while(~scanf("%d %d", &k, &mod))
54     {
55         for(int i = 0; i < 9; i++)
56         {
57             for(int j = 0; j < 10; j++)
58             {
59                 if(j == i + 1) a.m[i][j] = 1;
60                 else a.m[i][j] = 0;
61             }
62         }
63 
64         for(int i = 9; i >= 0; i--)
65         {
66             scanf("%d", &a.m[9][i]);
67         }
68 
69         if(k <= 9)
70         {
71             printf("%d\n", k % mod);
72             continue;
73         }
74 
75         int ans = 0;
76         MT b = Product(a, k-9);
77 
78         for(int i = 0; i < 10; i++)
79         {
80             ans += b.m[9][i]*i % mod;
81         }
82 
83         printf("%d\n", ans % mod);
84     }
85     return 0;
86 }
View Code

 

posted on 2015-11-07 21:21  改写历史,倾尽天下  阅读(215)  评论(0编辑  收藏  举报

导航