1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77
| int trie[MAX][26], fail[MAX], End[MAX], idx; int cnt[MAX], ans[MAX], in[MAX], per[MAX]; char s[MAX];
int newNode() { memset(trie[idx], 0, sizeof(trie[idx])); fail[idx] = End[idx] = 0; return idx++; }
void init() { idx = 0; newNode(); }
void insert(char s[], int id) { int p = 0, len = strlen(s); for (int i = 0; i < len; i++) { int c = s[i] - 'a'; if (!trie[p][c]) trie[p][c] = newNode(); p = trie[p][c]; } if (End[p]) per[id] = End[p]; else End[p] = id; }
void build() { queue<int> q; for (int i = 0; i < 26; i++) if (trie[0][i]) q.push(trie[0][i]); while (q.size()) { int now = q.front(); q.pop(); for (int i = 0; i < 26; i++) { if (trie[now][i]) { fail[trie[now][i]] = trie[fail[now]][i]; q.push(trie[now][i]); ++in[fail[trie[now][i]]]; } else { trie[now][i] = trie[fail[now]][i]; } } } }
void query(char s[]) { int p = 0, len = strlen(s); for (int i = 0; i < len; i++) { p = trie[p][s[i] - 'a']; ++cnt[p]; } }
void topu() { queue<int> q; for (int i = 1; i <= idx; i++) if (!in[i]) q.push(i); while (q.size()) { int u = q.front(); q.pop(); ans[End[u]] = cnt[u]; int v = fail[u]; cnt[v] += cnt[u]; --in[v]; if (in[v] == 0) q.push(v); } }
int main() { int n; scanf("%d", &n); iota(per, per + n + 5, 0); init(); for (int i = 1; i <= n; i++) { scanf("%s", s); insert(s, i); } build(); scanf("%s", s); query(s); topu(); for (int i = 1; i <= n; i++) printf("%d\n", ans[per[i]]); return 0; }
|