luogu P1357 花园

传送门

神仙题

首先转化成0/1串没有问题

然后1的个数有限?限制条件M<=5?

状压吧孩子

f[i][S]表示第i位S局面下方案数

所以可以按照题意转移

然后转移只和S有关&N<=1e15

矩阵加速吧孩子

开一个32*32的矩阵表示状态之间的转移qwq

(话说错位这个地方想的时间挺长的)

等下!这是个环?

难不成要枚举断点

考虑矩阵里面元素的定义

m[i][j]^k表示i状态到j状态经过k步的方案数

所以∑m[i][i]^n(i∈1->32)就是答案

最终复杂度O(2^5^3*lg(1e15)) 勉强能过

Code:

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<algorithm>
 4 #include<cmath>
 5 #include<queue>
 6 #include<iostream>
 7 #define ms(a,b) memset(a,b,sizeof a)
 8 #define rep(i,a,n) for(int i = a;i <= n;i++)
 9 #define per(i,n,a) for(int i = n;i >= a;i--)
10 #define inf 2147483647
11 using namespace std;
12 typedef long long ll;
13 #define mod 1000000007
14 ll read() {
15     ll as = 0,fu = 1;
16     char c = getchar();
17     while(c < '0' || c > '9') {
18         if(c == '-') fu = -1;
19         c = getchar();
20     }
21     while(c >= '0' && c <= '9') {
22         as = as * 10 + c - '0';
23         c = getchar();
24     }
25     return as * fu;
26 }
27 struct Mt {
28     const static int M = 64;
29     ll a[M][M];
30     void init(int op) {
31     ms(a,0);
32     if(op == 1) rep(i,0,M-1) a[i][i] = 1;
33     }
34 
35     Mt operator * (const Mt &o) const {
36     Mt tmp;tmp.init(0);
37     rep(i,0,M-1) rep(j,0,M-1) rep(k,0,M-1) {
38         tmp.a[i][j] = (tmp.a[i][j] + a[i][k] * o.a[k][j] % mod) % mod;
39     }
40     return tmp;
41     }
42 
43     Mt operator ^ (ll b) const {
44     Mt r = *this;
45     Mt tmp;tmp.init(1);
46     while(b) {
47         if((b) & 1) tmp = tmp * r;
48         r = r * r;
49         (b) >>= 1;
50     }
51     return tmp;
52     }
53 }x;
54 //head
55 ll n,m,k,ans;
56 int stat[40];
57 #define low(x) ((x)&(-(x)))
58 int judgeI(ll x) {
59     int tmp = 0;
60     for(int i = x;i;i -= low(i)) tmp++;
61     return tmp;
62 }
63 
64 int main() {
65     n = read(),m = read(),k = read();
66     int Max = 0;
67     rep(i,0,(1<<m)-1) 
68     if(judgeI(i) <= k) stat[++Max] = i;
69     rep(i,1,Max) rep(j,1,Max) {
70     int xx = stat[i] % (1<<m-1);
71     int yy = stat[j] >> 1;
72     if(xx == yy) {
73         x.a[stat[i]][stat[j]] = 1;
74     }
75     }
76     x = x ^ (n);
77     rep(i,1,Max) ans = (ans + x.a[stat[i]][stat[i]]) % mod;
78     printf("%lld\n",ans);
79     return 0;
80 }  

最后自己还是能写出来矩阵加速的题还是比较开心的

posted @ 2018-11-08 17:17  白怀潇  阅读(160)  评论(0编辑  收藏  举报