HDU 2222 Keywords Search(AC自动机模板题)
学习AC自动机请戳这里:大神blog........
自动机的模板:
#include <iostream> #include <algorithm> #include <cmath> #include <cstdio> #include <cstdlib> #include <cstring> #include <string> #include <vector> #include <set> #include <queue> #include <stack> #include <climits>//形如INT_MAX一类的 #define MAX 100005 #define INF 0x7FFFFFFF #define REP(i,s,t) for(int i=(s);i<=(t);++i) #define ll long long #define mem(a,b) memset(a,b,sizeof(a)) #define mp(a,b) make_pair(a,b) #define L(x) x<<1 #define R(x) x<<1|1 # define eps 1e-5 //#pragma comment(linker, "/STACK:36777216") ///传说中的外挂 using namespace std; struct trie { trie *fail; //失败指针 trie *next[26]; int cnt; trie () { fail = 0;cnt = 0; memset(next,0,sizeof(next)); } }*q[511111]; //模拟队列 trie *rt; int head,tail; char keyword[51]; char book[1111111]; void insert(char *key) { trie *p = rt; int t; while(*key) { t = *key - 'a'; if(p->next[t] == NULL) p->next[t] = new trie(); p = p->next[t]; key++; } p->cnt++; //表示一个单词 } void bfs() { rt->fail = NULL; //根结点fail指向空 q[head++] = rt; while(head != tail) { trie *t = q[tail++]; trie *p = NULL; for(int i=0; i<26; i++) { if(t->next[i] != NULL) { //对所有儿子的fail指针匹配并且入队 if(t == rt) t ->next[i]->fail = rt; //如果刚从根节点出发 else { //否则沿着他父亲的失败指针走, //直到走到一个节点,他的儿子中也有相同字符的节点。然后把当前节点的失败指针指向他的那个儿子 p = t->fail; while(p != NULL) { if(p->next[i] != NULL) { t->next[i]->fail = p->next[i]; break; } p = p->fail; } if(p == NULL) t->next[i]->fail = rt; //如果一直走到了root都没找到,那就把失败指针指向root } q[head++] = t->next[i]; } } } } int query(char *key) { trie *p = rt; int cnt = 0; while(*key) { int t = *key - 'a'; while(p->next[t] == NULL && p != rt) p = p->fail; //如果当前字符不匹配 p = p->next[t]; if(p == NULL) p = rt; //最终还是未匹配 trie *tmp = p; while(tmp != rt && tmp->cnt != -1) { cnt += tmp->cnt; tmp->cnt = -1; //该处已经出现过了 tmp = tmp->fail; } key++; } return cnt; } int main(){ int T; cin >> T; while(T --) { rt = new trie(); int n; cin >> n; for(int i=0; i<n; i++) { scanf("%s",keyword); insert(keyword); } head = 0; tail = 0; bfs(); scanf("%s",book); printf("%d\n",query(book)); } return 0; }