ACM-ICPC 2018 焦作赛区网络预赛 L. Poor God Water 矩阵快速幂

题目链接(VJ):https://nanti.jisuanke.com/t/A2022

计蒜客:https://nanti.jisuanke.com/t/A2022

题意:有N个小时,有三种食物(用1 ,2 ,3代替好了),每个小时要吃一种食物,要求任意连续三个小时不能出现111,222,333,132,231,313,323

的方案数

题解:最重要的是能找到这个转移关系,转移就是在增加一种食物,可以根据要求推出下面的递推矩阵.

 

 然后直接矩阵快速幂就好了。

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 const int MOD = 1e9+7;
 4 const int maxn = 20;
 5 #define mod(x) ((x)%MOD)
 6 typedef long long ll;
 7 struct martix{
 8     ll a[maxn][maxn];
 9     friend martix operator * (martix x,martix y)
10     {
11         martix ans;
12         for(int i = 1;i <= 9;i++)
13         {
14             for(int j = 1;j <= 9;j++)
15             {
16                 ll res = 0;
17                 for(int k = 1;k <= 9;k++) 
18                     res += mod((ll)x.a[i][k]*y.a[k][j]);
19                 ans.a[i][j] = mod(res);
20             }
21         }
22         return ans;
23     }
24     friend martix operator ^ (martix x,ll n)
25     {
26         martix unit;
27         memset(unit.a,0,sizeof(unit.a));
28         for(int i = 1;i <= 9;i++) unit.a[i][i] = 1; 
29         while(n)
30         {
31             if(n&1) unit = unit * x;
32             x = x * x;
33             n >>= 1;
34         }
35         return unit;
36     }
37 };
38 int main()
39 {
40     ll t,n;
41     cin>>t;
42     while(t--)
43     {
44         cin>>n;
45         if(n == 1) cout<<3<<endl;
46         else if(n == 2) cout<<9<<endl;
47         else
48         {
49             martix ans;
50             ll num[10][10] = {
51             0,0,0,0,0,0,0,0,0,0,
52             0,0,1,1,0,0,0,0,0,0,
53             0,0,0,0,0,1,1,0,0,0,
54             0,0,0,0,0,0,0,0,1,1,
55             0,1,1,0,0,0,0,0,0,0,
56             0,0,0,0,1,0,1,0,0,0,
57             0,0,0,0,0,0,0,1,1,1,
58             0,1,0,1,0,0,0,0,0,0,
59             0,0,0,0,1,1,1,0,0,0,
60             0,0,0,0,0,0,0,1,1,0,
61             };
62             for(int i = 1;i <= 9;i++)
63             {
64                 for(int j = 1;j <= 9;j++)
65                 {
66                     ans.a[i][j] = num[i][j];
67                 } 
68             }
69             ans = ans ^ (n-2);
70             ll res = 0;
71             for(int i = 1;i <= 9;i++)
72             {
73                 for(int j = 1;j <= 9;j++)
74                 {
75                     res += mod(ans.a[i][j]);
76                 }
77             }
78             cout<<mod(res)<<endl;
79         }
80     }
81     return 0;
82 }

 

posted @ 2020-03-01 14:04  Maynerd  阅读(248)  评论(0)    收藏  举报