这是一个AC自动机+dp的问题,在中间的串的处理可以枚举中断点来插入自动机内来实现,具体参见代码。

  在这题上不止为何一直MLE,一直找不到结果(lyf相同写法的代码消耗内存较少),还好考虑到这题节点应该不会过多,可以少开一点节点数。

  代码如下:

  1 #include <bits/stdc++.h>
  2 using namespace std;
  3 //const int N = 5e4 + 5;
  4 //const int MAX_Tot = 6 * 20 * 20 + 6 * 20 + 100;
  5 const int MAX_Tot = 500;
  6 typedef long long ll;
  7 const int mod = 998244353;
  8 
  9 int T, n, L;
 10 void add(int &a, int b)
 11 {
 12     a += b;
 13     if(a >= mod) a -= mod;
 14     if(a < 0) a += mod;
 15 }
 16 struct Aho
 17 {
 18     struct state
 19     {
 20         int nxt[2];
 21         int fail;
 22         int ed, vis;
 23     }stateTable[MAX_Tot];
 24 
 25     int size;
 26 
 27     queue<int> que;
 28 
 29     void init()
 30     {
 31         while(que.size()) que.pop();
 32         for(int i=0;i<MAX_Tot;i++)
 33         {
 34             memset(stateTable[i].nxt,0,sizeof(stateTable[i].nxt));
 35             stateTable[i].fail = stateTable[i].ed = stateTable[i].vis = 0;
 36         }
 37         size = 1;
 38     }
 39 
 40     void insert(char *s,int which,int type)
 41     {
 42         int n = strlen(s);
 43         int now = 0;
 44         for(int i=0;i<n;i++)
 45         {
 46             char c = s[i];
 47             if(!stateTable[now].nxt[c-'0'])
 48                 stateTable[now].nxt[c-'0'] = size++;
 49             now = stateTable[now].nxt[c-'0'];
 50         }
 51         if(type == 1) stateTable[now].ed |= (1<<which);
 52         else stateTable[now].vis |= (1<<which);
 53     }
 54 
 55     void build()
 56     {
 57         stateTable[0].fail = -1;
 58         que.push(0);
 59 
 60         while(que.size())
 61         {
 62             int u = que.front();que.pop();
 63             for(int i=0;i<2;i++)
 64             {
 65                 if(stateTable[u].nxt[i])
 66                 {
 67                     if(u == 0) stateTable[stateTable[u].nxt[i]].fail = 0;
 68                     else
 69                     {
 70                         int v = stateTable[u].fail;
 71                         while(v != -1)
 72                         {
 73                             if(stateTable[v].nxt[i])
 74                             {
 75                                 stateTable[stateTable[u].nxt[i]].fail = stateTable[v].nxt[i];
 76                                 stateTable[stateTable[u].nxt[i]].ed |= stateTable[stateTable[stateTable[u].nxt[i]].fail].ed;
 77                                 stateTable[stateTable[u].nxt[i]].vis |= stateTable[stateTable[stateTable[u].nxt[i]].fail].vis;
 78                                 break;
 79                             }
 80                             v = stateTable[v].fail;
 81                         }
 82                         if(v == -1) stateTable[stateTable[u].nxt[i]].fail = 0;
 83                     }
 84                     que.push(stateTable[u].nxt[i]);
 85                 }
 86                 /*****建立自动机nxt指针*****/
 87                 else
 88                 {
 89                     if(u == 0) stateTable[u].nxt[i] = 0;
 90                     else
 91                     {
 92                         int p = stateTable[u].fail;
 93                         while(p != -1 && stateTable[p].nxt[i] == 0) p = stateTable[p].fail;
 94                         if(p == -1) stateTable[u].nxt[i] = 0;
 95                         else stateTable[u].nxt[i] = stateTable[p].nxt[i];
 96                     }
 97                 }
 98                 /*****建立自动机nxt指针*****/
 99             }
100         }
101     }
102 
103     int dp[110][MAX_Tot][1<<6];
104     void solve()
105     {
106         memset(dp,0,sizeof dp);
107         dp[0][0][0] = 1;
108         for(int i=1;i<=L;i++)
109         {
110             for(int j=0;j<size;j++)
111             {
112                 for(int k=0;k<(1<<n);k++)
113                 {
114                     for(int ch=0;ch<2;ch++)
115                     {
116                         int now = stateTable[j].nxt[ch];
117                         int nowS = stateTable[now].ed;
118                         add(dp[i][now][k|nowS], dp[i-1][j][k]);
119                     }
120                 }
121             }
122         }
123         int ans = 0;
124         for(int i=0;i<size;i++)
125         {
126             for(int j=0;j<(1<<n);j++)
127             {
128                 if((stateTable[i].vis | j) == (1<<n)-1)
129                 {
130                     add(ans, dp[L][i][j]);
131                 }
132             }
133         }
134         printf("%d\n",ans);
135     }
136 }aho;
137 char s[50],t[50];
138 void work(int fenge,int which)
139 {
140     int f = fenge;
141     int you = fenge + 1;
142     bool can = 1;
143     int len = strlen(s);
144     while(1)
145     {
146         if(s[fenge] == s[you])
147         {
148             can = 0;
149             break;
150         }
151         fenge--; you++;
152         if(fenge < 0 || you >= len) break;
153     }
154     if(!can) return ;
155     fenge = f;
156     if((fenge+1) * 2 <= len)
157     {
158         for(int i=0;i<len-(fenge+1);i++) t[i] = s[len-1-i] == '1' ? '0' : '1'; t[len-(fenge+1)] = 0;
159         aho.insert(t,which,2);
160     }
161     else
162     {
163         for(int i=0;i<=fenge;i++) t[i] = s[i]; t[fenge+1] = 0;
164         aho.insert(t,which,2);
165     }
166 }
167 
168 int main()
169 {
170     scanf("%d",&T);
171     while(T--)
172     {
173         aho.init();
174         scanf("%d%d",&n,&L);
175         for(int i=0;i<n;i++)
176         {
177             scanf("%s",s);
178             int len = strlen(s);
179             aho.insert(s,i,1);
180             for(int j=0;j<len;j++) t[j] = s[len-j-1] == '1' ? '0' : '1'; t[len] = 0;
181             aho.insert(t,i,1);
182             for(int j=0;j<len-1;j++) work(j,i);
183         }
184         aho.build();
185         aho.solve();
186     }
187     return 0;
188 }