FZoj--2117(DP,矩阵快速幂)

2014-11-18 17:25:19

思路:dp[i][a][b],表示确定了i个数位,7的奇偶情况是a,9的奇偶情况是b,然后发现n很大,显然用矩阵加速。

  右侧单列矩阵四个元素分别是:奇奇、奇偶、偶奇、偶偶的情况,然后构造一下左侧矩阵就行了。

  (这里可以把4*4矩阵优化成3*3,因为发现奇偶和偶奇的情况值是一样的,思考)

  注意:把算过的转移矩阵记忆下来能优化不少的时间。

 1 /*************************************************************************
 2     > File Name: 2117.cpp
 3     > Author: Nature
 4     > Mail: 564374850@qq.com
 5     > Created Time: Tue 18 Nov 2014 04:23:57 PM CST
 6 ************************************************************************/
 7 
 8 #include <cstdio>
 9 #include <cstring>
10 #include <cstdlib>
11 #include <cmath>
12 #include <vector>
13 #include <map>
14 #include <set>
15 #include <stack>
16 #include <queue>
17 #include <iostream>
18 #include <algorithm>
19 using namespace std;
20 #define lp (p << 1)
21 #define rp (p << 1|1)
22 #define getmid(l,r) (l + (r - l) / 2)
23 #define MP(a,b) make_pair(a,b)
24 typedef long long ll;
25 const int INF = 1 << 30;
26 const int mod = 1000000007;
27 
28 int T,cnt;
29 ll n;
30 
31 struct Mx{
32     ll a[3][3];
33     void clear(){ memset(a,0,sizeof(a));}
34     void stand(){ memset(a,0,sizeof(a)); for(int i = 0; i < 3; ++i) a[i][i] = 1;}
35     Mx operator * (Mx b){
36         Mx c;
37         c.clear();
38         for(int i = 0; i < 3; ++i){
39             for(int j = 0; j < 3; ++j){
40                 for(int k = 0; k < 3; ++k){
41                     c.a[i][j] = (c.a[i][j] + (a[i][k] * b.a[k][j]) % mod) % mod;
42                 }
43             }
44         }
45         return c;
46     }
47 };
48 
49 Mx t[100];
50 
51 Mx Q_pow(ll num){
52     Mx res,tem = t[1];
53     int v = 1;
54     res.stand();
55     while(num){
56         if(num & 1) res = res * tem;
57         v++;
58         if(cnt >= v) tem = t[v];
59         else{
60             tem = tem * tem;
61             t[++cnt] = tem;
62         }
63         num >>= 1;
64     }
65     return res;
66 }
67 
68 int main(){
69     cnt = 1;
70     t[1].clear();
71     t[1].a[0][0] = 3;
72     t[1].a[0][1] = 2;
73     t[1].a[1][0] = 1;
74     t[1].a[1][1] = 3;
75     t[1].a[1][2] = 1;
76     t[1].a[2][1] = 2;
77     t[1].a[2][2] = 3;
78     scanf("%d",&T);
79     while(T--){
80         scanf("%I64d",&n);
81         Mx ans;
82         ans.clear();
83         ans.a[2][0] = 1;
84         ans = Q_pow(n) * ans;
85         printf("%I64d\n",ans.a[2][0]);
86     }
87     return 0;
88 }

 

posted @ 2014-11-18 17:29  Naturain  阅读(432)  评论(0编辑  收藏  举报