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 78 79
| #include <cstdio> #include <cstring> #include <cstdlib> #include <vector> #include <algorithm> #include <cmath> #include <cctype> #include <iostream> #include <bitset> #include <queue> #include <climits> const int MAXN = 1000 + 10; struct Node { int id, cnt; Node *next[28], *fail; Node() { id = -1, cnt = 0, fail = 0, memset(next, 0, sizeof(next)); } } *root; inline void insert(const char *s, int id) { register int len = strlen(s); Node *p = root; for (register int i = 0; i < len; i++) { if (!p->next[s[i] - 'A']) p->next[s[i] - 'A'] = new Node(); p = p->next[s[i] - 'A']; } p->cnt++, p->id = id; } inline void build() { Node *p, *next; std::queue<Node *> q; q.push(root); while (!q.empty()) { p = q.front(), q.pop(); for (register int i = 0; i < 28; ++i) { if (p->next[i]) { next = p->fail; while (next && !next->next[i]) next = next->fail; p->next[i]->fail = (next ? next->next[i] : root), q.push(p->next[i]); } } } } inline void clear(Node *p) { for (register int i = 0; i < 26; ++i) if (p->next[i]) clear(p->next[i]); delete p; } char s[MAXN][55], T[2000005]; int cnt[MAXN]; inline void query(const char *s) { register int index, len = strlen(s); Node *p = root; for (register int i = 0; i < len; i++) { if (isupper(s[i])) index = s[i] - 'A'; else index = 27; while (!p->next[index] && p != root) p = p->fail; p = p->next[index]; if (!p) p = root; Node *tmp = p; while (tmp != root && (~tmp->id)) ::cnt[tmp->id]++, tmp = tmp->fail; } }
int main() { #ifndef ONLINE_JUDGE freopen("in.in", "r", stdin); #endif std::ios::sync_with_stdio(0), std::cin.tie(0); int n; while (std::cin >> n) { root = new Node(); memset(cnt, 0, sizeof(cnt)); for (register int i = 0; i < n; i++) std::cin >> s[i], insert(s[i], i); build(), std::cin >> T, query(T); for (register int i = 0; i < n; i++) { if (cnt[i]) std::cout << s[i] << ": " << cnt[i] << "\n"; } clear(root); } return 0; }
|