#include<bits/stdc++.h> usingnamespace std; constint maxn = 1e4 + 7; structaho { int size; structnode { int next[26]; int fail, cnt; node() { memset(next, 0, sizeof(next)); fail = cnt = 0; } } treeNode[maxn]; queue<int> q; voidinit() { while (!q.empty()) { q.pop(); } for (int i = 0; i < maxn; ++i) { memset(treeNode[i].next, 0, sizeof(treeNode[i].next)); treeNode[i].fail = treeNode[i].cnt = 0; } size = 0; } voidinsert(string s) { int cur = 0; for (int i = 0; i < s.length(); ++i) { int num = s[i] - 'a'; if (!treeNode[cur].next[num]) { treeNode[cur].next[num] = ++size; } cur = treeNode[cur].next[num]; } treeNode[cur].cnt++; }
voidbuild() { treeNode[0].fail = -1; queue<int> q; q.push(0); while (!q.empty()) { int top = q.front(); q.pop(); for (int i = 0; i < 26; ++i) { if (treeNode[top].next[i]) { q.push(treeNode[top].next[i]); if (top == 0) { treeNode[treeNode[top].next[i]].fail = 0; } else {
int v = treeNode[top].fail; while (v != -1) {
if (treeNode[v].next[i]) { treeNode[treeNode[top].next[i]].fail = treeNode[v].next[i]; break; } else { v = treeNode[v].fail; } } if (v == -1) { treeNode[treeNode[top].next[i]].fail = 0; } } } } } }
intgetNow(int cur) { int ret = 0; while (cur != -1) { ret += treeNode[cur].cnt; treeNode[cur].cnt = 0; cur = treeNode[cur].fail; } return ret; }
intfind(string target) { int res = 0; int pos = 0, cur = 0; while (pos < target.length()) { if (treeNode[cur].cnt) { res += getNow(cur); } int num = target[pos] - 'a'; if (cur == -1) { ++pos; cur = 0; } elseif (treeNode[cur].next[num]) { ++pos; cur = treeNode[cur].next[num]; } else { cur = treeNode[cur].fail; } } if (treeNode[cur].cnt) { res += getNow(cur); } return res; } // 用来检查构建的字典树和fail指针的指向 voidcheck() { int cur = 0; structpair { int v; string word; pair(int v, string word) : v(v), word(word){}; }; queue<pair> q; q.push(pair(0, "")); while (!q.empty()) { pair top = q.front(); q.pop(); for (int i = 0; i < 26; ++i) { if (treeNode[top.v].next[i]) {