#include #include #include #include using namespace std; const int N = 2 * 1e5 + 10; const int M = 2 * 1e6 + 10; char s[N], T[M]; int n; int tr[N][26], idx, ne[N]; int id[N]; int cnt[N]; int family[N]; void insert(char *s, int x) { int p = 0; for (int i = 0; s[i]; i++) { int t = s[i] - 'a'; if (!tr[p][t]) tr[p][t] = ++idx; p = tr[p][t]; } if (!id[p]) id[p] = x; // id[p]记录的是首个入驻的模式串号x family[x] = id[p]; // 将所有最终位置是p号节点,也就是重复模式串,都划归到family[x]这个首次入驻模式串x为同一家族 } int q[N], hh, tt = -1; void bfs() { for (int i = 0; i < 26; i++) if (tr[0][i]) q[++tt] = tr[0][i]; while (hh <= tt) { int p = q[hh++]; for (int i = 0; i < 26; i++) { int t = tr[p][i]; if (!t) tr[p][i] = tr[ne[p]][i]; else { ne[t] = tr[ne[p]][i]; q[++tt] = t; } } } } void query(char *s) { int p = 0; for (int i = 0; s[i]; i++) { p = tr[p][s[i] - 'a']; for (int j = p; j; j = ne[j]) if (id[j]) cnt[id[j]]++; } } int main() { //加快读入 ios::sync_with_stdio(false), cin.tie(0); cin >> n; for (int i = 1; i <= n; i++) { cin >> s; insert(s, i); } bfs(); cin >> T; query(T); for (int i = 1; i <= n; i++) printf("%d\n", cnt[family[i]]); return 0; }