structtrie { int nxt[N][26], cnt; bool exist[N]; voidinsert(char *s, int l) { int p = 0; for (int i = 0; i < l; i++) { int c = s[i] - 'a'; if (!nxt[p][c]) nxt[p][c] = ++cnt; p = nxt[p][c]; } exist[p] = 1; } boolfind(char *s, int l) { int p = 0; for (int i = 0; i < l; i++) { int c = s[i] - 'a'; if (!nxt[p][c]) return0; p = nxt[p][c]; } return exist[p]; } };
voidbuild() { queue<int> q; for (int i = 0; i < 26; i++) tr[0][i] && (q.push(tr[0][i]), 0); while (!q.empty()) { int t = q.front(); q.pop(); for (int i = 0; i < 26; i++) { int &p = tr[t][i]; if (!p) p = tr[nxt[t]][i]; else { nxt[p] = tr[nxt[t]][i]; q.push(p); } } } } voidinsert(int k, int len, char *str) { int p = 0; for (int i = 1; i <= len; i++) { int &t = tr[p][str[i] - 'a']; !t && (t = ++idx); p = t; cnt[p] = true; } id[k] = p; } voiddfs(int x) { for (int i : g[x]) { dfs(i); f[x] += f[i]; } } intmain() { read(n); for (int i = 1; i <= n; i++) { scanf("%s", s + 1); insert(i, strlen(s + 1), s); } build(); scanf("%s", str + 1); int m = strlen(str + 1); for (int i = 1, p = 0; i <= m; i++) { int t = str[i] - 'a'; p = tr[p][t]; f[p] += cnt[p]; } for (int i = 1; i <= idx; i++) g[nxt[i]].push_back(i); dfs(0); for (int i = 1; i <= n; i++) write(f[id[i]]), puts(""); return0; }