标签:
#include <cstdio> #include <cstdlib> #include <cstring> #include <queue> using namespace std; const int N = 5e5+5, M = 1e6+5; struct Trie { Trie *next[26]; Trie *fail; int val; }tree[N]; queue <Trie *> q; int idx[128]; class ac_auto { private: int nxt; Trie *root; public: ac_auto() { nxt = 0; root = add(); } Trie *add() { memset(&tree[nxt], 0, sizeof(Trie)); tree[nxt].fail = root; return &tree[nxt++]; } void insert(char *s) { Trie *rt = root; int len = strlen(s); for(int i = 0; i < len; i++) { int c = idx[s[i]+0]; if(!rt->next[c]) rt->next[c] = add(); rt = rt->next[c]; } rt->val++; } void get_f() { queue <Trie *> q; q.push(root); root->fail = NULL; while(!q.empty()) { Trie *u = q.front(); q.pop(); for(int c = 0; c < 26; c++) { if(u->next[c]) { Trie *f = u->fail; while(f) { if(f->next[c]) { u->next[c]->fail = f->next[c]; break; } f = f->fail; } if(!f) u->next[c]->fail = root; q.push(u->next[c]); } } } } int match(char *s) { Trie *rt = root; int len = strlen(s), ret = 0; for(int i = 0; i < len; i++) { int c = idx[s[i]+0]; while(!rt->next[c] && rt != root) rt = rt->fail; rt = rt->next[c]; if(!rt) rt = root; Trie *p = rt; while(p != root) { if(p->val) { ret += p->val; p->val = 0; } else break; p = p->fail; } } return ret; } }; void haxi() { for(int i = 0; i < 26; i++) idx['a'+i] = i; } int main() { haxi(); int T, m; char str[M]; scanf("%d", &T); while(T--) { ac_auto ac; scanf("%d", &m); while(m--) { scanf("%s", str); ac.insert(str); } ac.get_f(); scanf("%s", str); int ans = ac.match(str); printf("%d\n", ans); } return 0; }
标签:
原文地址:http://blog.csdn.net/j_sure/article/details/42044207