AC自动机模版题
#include<iostream>
#include<queue>
#include<algorithm>
#include<cmath>
#include<cstdio>
#include<string>
#include<cstring>
using namespace std;
//可优化为数组形式
struct node{
node* next[26];
node* fail;
int value;
node() {
for(int i = 0; i < 26; i++) next[i] = NULL;
fail = NULL;
value = 0;
}
};
node* root;
queue<node*> q;
void insert(string s) {
int l =(int)s.length();
node* p = root;
for(int i = 0; i < l; i++) {
int id = s[i]-'a';
if(p->next[id] == NULL) p->next[id] = new node();
p = p->next[id];
}
p->value++; //作为一个单词匹配的标记
}
void setfail() {
q.push(root);
while(!q.empty()) {
node* now = q.front(); q.pop();//取出下一个,出队
for(int i = 0 ; i < 26; i++) if(now->next[i]) {//节点存在,为它构建fail指针
node *p = now->fail;
while(p && !p->next[i]) p = p->fail; //如果now为root,则fail为NULL
now->next[i]->fail = p ? p->next[i] : root;//赋值
q.push(now->next[i]);//入队
}
}
}
int ac(string s) {
int l = (int)s.length();
node* now = root;
int cnt = 0;
for(int i = 0; i < l; i++) {
int id = (int)(s[i] - 'a');
while(now && !now->next[id]) now = now->fail;//找到匹配的位置,//千万不能写反
now = now ? now->next[id] : root;
for(node* p = now; p ; p= p->fail) if(p->value > 0) {
cnt += p->value;
p->value = 0;
}
}
return cnt;
}
void clear(node* p) {
for(int i = 0; i < 26; i++) if(p->next[i]) clear(p->next[i]);
delete p;
}
int main() {
//freopen("a.in", "r", stdin);
ios::sync_with_stdio(false);
int T; cin >> T;
string s;
while(T--) {
//初始化
root = new node();
int N; cin >> N;
while(N--) {
cin >> s;
insert(s);
}
cin >> s;
setfail();
cout << ac(s) << endl;
clear(root);
}
return 0;
}