首页 > 代码库 > HDU5950(矩阵快速幂)

HDU5950(矩阵快速幂)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5950

题意:f(n) = f(n-1) + 2*f(n-2) + n^4,f(1) = a , f(2) = b,求f(n)

思路:对矩阵快速幂的了解仅仅停留在fib上,重现赛自己随便乱推还一直算错,快两个小时才a还wa了好几次....

主要就是构造矩阵:(n+1)^4 = n^4 + 4n^3 + 6n^2 + 4n + 1

 

|1   2   1   4   6   4   1|     |   f(n+1)   |           |    f(n+2)    |

|1   0   0   0   0   0   0|     |     f(n)     |           |    f(n+1)    |

|0   0   1   4   6   4   1|     | (n+1)^4  |           |  (n+2)^4   |

|0   0   0   1   3   3   1|  * | (n+1)^3  |     =    |  (n+2)^3   |

|0   0   0   0   1   2   1|     | (n+1)^2  |           |  (n+2)^2  |

|0   0   0   0   0   1   1|     |    n+1     |           |     n+2      |

|0   0   0   0   0   0   1|     |      1       |           |       1        |

 

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

 

HDU5950(矩阵快速幂)