调了4个小时多...
/* Forgive me Not */
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int maxn = 100005, maxl = 5000005, maxq = maxn;
int n, q[maxq];
char str[maxl], tmp[maxl];
struct _acm {
int son[maxn][2], ch[maxn][2], fail[maxn], sum[maxn], cnt;
bool flag[maxn];
void init() {
for(int i = 0; i < maxn; i++) ch[i][0] = ch[i][1] = son[i][0] = son[i][1] = fail[i] = sum[i] = flag[i] = 0;
cnt = 0;
}
void insert() {
int now = 0;
for(int i = 0; str[i]; i++) {
int &pos = ch[now][str[i] - '0'];
if(!pos) pos = ++cnt;
now = pos;
}
flag[now] = 1;
}
void getfail() {
for(int i = 0; i <= cnt; i++) sum[i] = flag[i], son[i][0] = ch[i][0], son[i][1] = ch[i][1];
int h = 0, t = 0;
for(int i = 0; i < 2; i++) if(son[0][i]) q[t++] = son[0][i];
while(h != t) {
int u = q[h++];
for(int i = 0; i < 2; i++)
if(!son[u][i]) son[u][i] = son[fail[u]][i];
else {
fail[q[t++] = son[u][i]] = son[fail[u]][i];
sum[son[u][i]] += sum[fail[son[u][i]]];
}
}
}
int query() {
int now = 0, res = 0;
for(int i = 0; str[i]; i++) {
now = son[now][str[i] - '0'];
res += sum[now];
}
return res;
}
bool find() {
int now = 0;
for(int i = 0; str[i]; i++) {
int pos = ch[now][str[i] - '0'];
if(!pos) return 0;
now = pos;
}
return flag[now];
}
} big, small;
inline void dfs(int x, int y) {
for(int i = 0; i < 2; i++) if(small.ch[x][i]) {
if(!big.ch[y][i]) big.ch[y][i] = ++big.cnt;
big.flag[big.ch[y][i]] |= small.flag[small.ch[x][i]];
dfs(small.ch[x][i], big.ch[y][i]);
}
}
inline void combine() {
dfs(0, 0);
small.init();
big.getfail();
}
int main() {
int T; scanf("%d", &T);
for(int cas = 1; cas <= T; cas++) {
big.init(); small.init();
printf("Case #%d:\n", cas);
scanf("%d", &n);
int ans = 0;
while(n--) {
scanf("%s", tmp);
int len = strlen(tmp) - 1, l = 0;
for(int i = ans % len + 1; i <= len; i++) str[l++] = tmp[i];
len = ans % len;
for(int i = 1; i <= len; i++) str[l++] = tmp[i];
str[l] = '\0';
if(tmp[0] == '+') {
if(small.find() || big.find()) continue;
small.insert();
small.getfail();
if(small.cnt > 1500) combine();
} else printf("%d\n", ans = big.query() + small.query());
}
}
}