UVA Recurrences 矩阵相乘+快速幂

题目大意:

  f(n) = a1 f(n - 1) + a2 f(n - 2) + a3 f(n - 3) + ... + ad f(n - d),已给递推公式,求f(n)的大小。

解题思路:

  n很大,所以我们就要构造矩阵,运用矩阵快速幂来求解。//题目描述上口口声声说int范围内,但是大家一定不要天真!!!!!!

 1 #include <iostream>
 2 #include <cstdlib>
 3 #include <cstdio>
 4 #include <algorithm>
 5 #include <vector>
 6 #include <queue>
 7 #include <cstring>
 8 using namespace std;
 9 
10 #define LL long long
11 const int maxn = 18;
12 LL d, m;
13 struct mat
14 {
15     LL p[maxn][maxn];
16 };
17 
18 mat mul (mat a, mat b);
19 mat pow (LL n, mat a, mat b);
20 
21 int main ()
22 {
23     LL n;
24     mat a, b;
25 
26     while (scanf ("%lld %lld %lld", &d, &n, &m), n+m+d)
27     {
28         memset (a.p, 0, sizeof(a.p));
29         memset (b.p, 0, sizeof(b.p));
30 
31         for (int i=0; i<d; i++)//构造矩阵
32         {
33             scanf ("%lld", &a.p[i][0]);
34             a.p[i][0] %= m;
35             a.p[i][i+1] = 1;
36         }
37         for (int i=0; i<d; i++)//这个矩阵要反过来输入!!!!!!
38             {
39                 scanf ("%lld", &b.p[0][d-i-1]);
40                 b.p[0][i] %= m;
41             }
42 
43 
44         if (d < n)
45         {
46             b = pow (n-d, a, b);
47             printf ("%lld\n", b.p[0][0]);
48         }
49         else
50             printf ("%lld\n", b.p[0][d-n]);
51     }
52     return 0;
53 }
54 
55 mat mul (mat a, mat b)
56 {
57     mat c;
58     memset (c.p, 0, sizeof(c.p));
59     for (int i=0; i<d; i++)
60         for (int j=0; j<d; j++)
61         {
62             for (int k=0; k<d; k++)
63                 c.p[i][j] = (c.p[i][j] + a.p[i][k] * b.p[k][j]) % m;
64         }
65         return c;
66 }
67 mat pow (LL n, mat a, mat b)
68 {
69     while (n)
70     {
71         if (n % 2)
72             b = mul (b, a);
73         a = mul (a, a);
74         n /= 2;
75     }
76     return b;
77 }

 

posted @ 2015-03-23 20:58  罗茜  阅读(163)  评论(0编辑  收藏  举报