标签:
题目链接:Keywords Search
解析:直接开个end数组,统计一下即可。
PS:AC自动机的代码风格是参考bin神的。
AC代码:
#include <bits/stdc++.h> using namespace std; const int max_word = 500005; const int sigma_size = 26; const int max_text = 1000005; struct Trie{ int next[max_word][sigma_size], fail[max_word], end[max_word]; int root, L; int newnode(){ for(int i = 0; i < sigma_size; i++) next[L][i] = -1; end[L++] = 0; return L-1; } void init(){ L = 0; root = newnode(); } void insert(char buf[]){ int len = strlen(buf); int now = root; for(int i = 0; i < len; i++){ if(next[now][buf[i] - 'a'] == -1) next[now][buf[i] - 'a'] = newnode(); now = next[now][buf[i] - 'a']; } end[now] ++; } void build(){ queue<int> Q; fail[root] = root; for(int i = 0; i < sigma_size; i++){ if(next[root][i] == -1) next[root][i] = root; else{ fail[ next[root][i] ] = root; Q.push(next[root][i]); } } while(!Q.empty()){ int now = Q.front(); Q.pop(); for(int i = 0; i < sigma_size; i++){ if(next[now][i] == -1) next[now][i] = next[ fail[now] ][i]; else{ fail[ next[now][i] ] = next[ fail[now] ][i]; Q.push(next[now][i]); } } } } int query(char buf[]){ int len = strlen(buf); int now = root; int res = 0; for(int i = 0; i < len; i++){ now = next[now][ buf[i] - 'a' ]; int temp = now; while(temp != root){ res += end[temp]; end[temp] = 0; temp = fail[temp]; } } return res; } void debug(){ for(int i = 0; i < L; i++){ printf("id = %3d, fail = %3d, end = %3d, chi = [", i, fail[i], end[i]); for(int j = 0; j < sigma_size; j++) printf("%2d", next[i][j]); printf("]\n"); } } }; char buf[max_text]; Trie ac; int main(){ #ifdef sxk freopen("in.txt", "r", stdin); #endif // sxk int T, n; scanf("%d", &T); while(T--){ scanf("%d", &n); ac.init(); for(int i = 0; i < n; i++){ scanf("%s", buf); ac.insert(buf); } ac.build(); scanf("%s", buf); printf("%d\n", ac.query(buf)); } return 0; }
版权声明:本文为博主原创文章,未经博主允许不得转载。
HDU 2222 Keywords Search (AC自动机)
标签:
原文地址:http://blog.csdn.net/u013446688/article/details/47170865