如题。而且并没有用什么玄学STL。 原题是P3808,AC自动机模板题。
#include <iostream>
#include <algorithm>
#include <queue>
#include <string.h>
using namespace std;
const int N = 1e6+10;
char s[N];
struct AC_Automaton{
int tr[N][26], cnt; //字典树
int exist[N]; // 该结点结尾的字符串是否存在,存在多少个
int fail[N]; //失配指针
queue<int> q; //用于bfs字典树的队列
void insert(char *s, int l) { // 插入字符串到字典树中
int p = 0;
for (int i = 0; i < l; i++) {
int c = s[i] - 'a';
if (!tr[p][c]) tr[p][c] = ++cnt; // 如果没有,就添加结点
p = tr[p][c];
}
exist[p]++;
}
void build(){ //构建fail指针和自动机
for(int i = 0; i < 26; i++)
if(tr[0][i]) q.push(tr[0][i]);
while(q.size()){
int u = q.front();
q.pop();
for(int i = 0; i < 26; i++){
if(tr[u][i]) //存在,不失配
fail[tr[u][i]] = tr[fail[u]][i], q.push(tr[u][i]);
else //不存在, 将会失配
tr[u][i] = tr[fail[u]][i];
}
}
}
int query(char *t){
int u = 0, res = 0;
for(int i = 0; t[i]; i++){
u = tr[u][t[i]-'a'];
for(int j = u; j && exist[j] != -1; j = fail[j])
res += exist[j], exist[j] = -1;
}
return res;
}
}AC;
int main()
{
int n; scanf("%d",&n);
for(int i = 0; i < n; i++)
{
scanf("%s",s);
int l = strlen(s);
// printf("%d\n\n",l);
AC.insert(s, l);
}
AC.build();
scanf("%s",s);
// printf("s = %d\n",strlen(s));
printf("%d\n",AC.query(s));
// system("pause");
}