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 80 81 82 83 84 85 86 87
| #include <cstdio> #include <cstring> #include <cstdlib> #include <vector> #include <algorithm> #include <cmath> #include <cctype> #include <iostream> #include <queue> char str[1000000 + 100]; struct Node { int cnt; Node *next[26]; Node *fail; inline Node *init() { return memset(next, 0, sizeof(next)), cnt = 0, fail = NULL, this; } } *root; template<class T, size_t size> struct MemoryPool { T buf[size], *st[size], *tail, *end; int top; MemoryPool() : top(0), tail(buf), end(buf + size) {} inline T *alloc() { if (top) return st[--top]; if (tail != end) return tail++; return new T; } inline void recycle(T *x) { if (top > size) delete x; else st[top++] = x; } }; MemoryPool<Node, 1000000> pool; inline void insert() { register int len = strlen(str); Node *p = root; for (register int k = 0; k < len; k++) { register int pos = str[k] - 'a'; if (p->next[pos] == NULL) p->next[pos] = pool.alloc()->init(), p = p->next[pos]; else p = p->next[pos]; } p->cnt++; } inline void build() { Node *p = root, *next; std::queue<Node *>q; q.push(root); while (!q.empty()) { p = q.front(), q.pop(); for (register int i = 0; i < 26; ++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 query() { register int len = strlen(str), cnt = 0; Node *p = root, *tmp; for (register int i = 0; i < len; i++) { register int pos = str[i] - 'a'; while (!p->next[pos] && p != root) p = p->fail; p = p->next[pos]; if (!p) p = root; tmp = p; while (tmp != root) { if (tmp->cnt >= 0) cnt += tmp->cnt, tmp->cnt = -1; else break; tmp = tmp->fail; } } printf("%d\n", cnt); } int main() { register int cas, n; scanf("%d", &cas); while (cas--) { root = pool.alloc()->init(); root->fail = NULL; scanf("%d", &n); getchar(); for (register int i = 0; i < n; i++) gets(str), insert(); build(), gets(str), query(); } return 0; }
|