constint N = 10010, M = 1000010, S = 55; int tr[N*S][26], cnt[N*S], ne[N*S], idx; char str[M];
voidinsert(){ int p = 0; for (int i = 0; str[i]; i++) { int t = str[i] - 'a'; if (!tr[p][t]) tr[p][t] = ++idx; p = tr[p][t]; } cnt[p]++; }
voidbuild(){ queue<int> q; for (int i = 0; i < 26; i++) { if (tr[0][i]) q.push(tr[0][i]); } while (q.size()) { int t = q.front(); q.pop(); for (int i = 0; i < 26; i++) { int p = tr[t][i]; if (!p) tr[t][i] = tr[ne[t]][i]; else { ne[p] = tr[ne[t]][i]; q.push(p); } } } }
intmain(){ int T, n; scanf("%d", &T); while (T--) { memset(tr, 0, sizeof tr); memset(cnt, 0, sizeof cnt); memset(ne, 0, sizeof ne); idx = 0; scanf("%d", &n); while (n--) { scanf("%s", str); insert(); } build(); scanf("%s", str); int res = 0; for (int i = 0, j = 0; str[i]; i++) { int t = str[i] - 'a'; j = tr[j][t]; for (int p = j; p; p = ne[p]) { res += cnt[p]; cnt[p] = 0; } } printf("%d\n", res); } return0; }
voidinsert(){ int p = 0; for (int i = 0; str[i]; i++) { int t = get(str[i]); if (!tr[p][t]) tr[p][t] = ++idx; p = tr[p][t]; } st[p] = true; }
voidbuild(){ queue<int> q; for (int i = 0; i < 4; i++) if (tr[0][i]) q.push(tr[0][i]); while (q.size()) { int t = q.front(); q.pop(); for (int i = 0; i < 4; i++) { int p = tr[t][i]; if (!p) tr[t][i] = tr[ne[t]][i]; else ne[p] = tr[ne[t]][i], q.push(p); } } }
boolcheck(int p){ for (; p; p = ne[p]) { if (st[p]) returnfalse; } returntrue; }
intsolve(){ memset(f, 0x3f, sizeof f); memset(tr, 0, sizeof tr); memset(ne, 0, sizeof ne); memset(st, 0, sizeof st); idx = 0; f[0][0] = 0; while (n--) { scanf("%s", str); insert(); } build(); scanf("%s", str+1); n = strlen(str+1); for (int i = 1; i <= n; i++) for (int j = 0; j <= idx; j++) for (int k = 0; k < 4; k++) { int cost = get(str[i]) != k; int p = tr[j][k]; if (check(p)) f[i][p] = min(f[i][p], f[i-1][j] + cost); } int res = INF; for (int j = 0; j <= idx; j++) res = min(res, f[n][j]); if (res == INF) return-1; return res; }
intmain(){ int T = 0; while (scanf("%d", &n), n) printf("Case %d: %d\n", ++T, solve()); return0; }
voidinsert(){ int p = 0; for (int i = 0; str[i]; i++) { int t = get(str[i]); if (!tr[p][t]) tr[p][t] = ++idx; p = tr[p][t]; } st[p] = true; }
voidbuild(){ queue<int> q; for (int i = 0; i < 4; i++) if (tr[0][i]) q.push(tr[0][i]); while (q.size()) { int t = q.front(); q.pop(); for (int i = 0; i < 4; i++) { int p = tr[t][i]; if (!p) tr[t][i] = tr[ne[t]][i]; else { ne[p] = tr[ne[t]][i]; q.push(p); st[p] |= st[ne[p]]; } } } }
intsolve(){ memset(tr, 0, sizeof tr); memset(ne, 0, sizeof ne); memset(st, 0, sizeof st); memset(f, 0x3f, sizeof f); idx = 0; f[0][0] = 0; while (n--) { scanf("%s", str); insert(); } build(); scanf("%s", str+1); n = strlen(str+1); for (int i = 1; i <= n; i++) for (int j = 0; j <= idx; j++) for (int k = 0; k < 4; k++) { int cost = get(str[i]) != k; int p = tr[j][k]; if (!st[p]) f[i][p] = min(f[i][p], f[i-1][j] + cost); } int res = INF; for (int j = 0; j <= idx; j++) res = min(res, f[n][j]); if (res == INF) res = -1; return res; }
intmain(){ int T = 0; while (scanf("%d", &n), n) printf("Case %d: %d\n", ++T, solve()); return0; }
constint N = 1e6+10; int tr[N][26], cnt[N], ne[N], q[N], id[210], n, idx; char str[N];
voidinsert(int x){ int p = 0; for (int i = 0; str[i]; i++) { int t = str[i] - 'a'; if (!tr[p][t]) tr[p][t] = ++idx; p = tr[p][t]; cnt[p]++; } id[x] = p; }
voidbuild(){ int hh = 0, tt = -1; for (int i = 0; i < 26; i++) if (tr[0][i]) q[++tt] = tr[0][i]; while (hh <= tt) { int t = q[hh++]; for (int i = 0; i < 26; i++) { int& p = tr[t][i]; if (!p) p = tr[ne[t]][i]; else ne[p] = tr[ne[t]][i], q[++tt] = p; } } }
intmain(){ scanf("%d", &n); for (int i = 1; i <= n; i++) { scanf("%s", str); insert(i); } build(); // 所有除了 0 的节点都要加进队列 一共有 idx+1 个 for (int i = idx-1; i >= 0; i--) { int t = q[i]; cnt[ne[t]] += cnt[t]; } for (int i = 1; i <= n; i++) printf("%d\n", cnt[id[i]]); return0; }