http://acm.hdu.edu.cn/showproblem.php?pid=2222
AC自动机
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include <stdio.h>
#include <string.h>
const int N=250010,B=26;
int trie[N][26];
int fail[N];
int key[N];
int size;
int que[N];
char s[1000100];
void insert(char *s)
{
int p=0,i;
for (i=0;s[i];i++)
{
int c=s[i]-'a';
if (!trie[p][c]) trie[p][c]=++size;
p=trie[p][c];
}
key[p]++;
}
void AC()
{
int front,rear,u,v,i;
front=rear=0;
for (i=0;i<B;i++) if (v=trie[0][i])
{
fail[v]=0;
que[rear++]=v;
}
while (front<rear)
{
u=que[front++];
for (i=0;i<B;i++) if (v=trie[u][i])
{
fail[v]=trie[fail[u]][i];
que[rear++]=v;
//key[v]=key[fail[v]];
}
else trie[u][i]=trie[fail[u]][i];
}
}
int match(char *s)
{
int cnt=0,p=0,i;
for (i=0;s[i];i++)
{
int c=s[i]-'a';
p=trie[p][c];
for (int q=p;q;q=fail[q])
{
cnt+=key[q];
key[q]=0;
}
}
return cnt;
}
int main()
{
int T;
scanf("%d",&T);
int n,i;
char w[60];
while (T--)
{
memset(trie,0,sizeof(trie));
memset(key,0,sizeof(key));
memset(fail,0,sizeof(fail));
size=0;
scanf("%d",&n);
for (i=0;i<n;i++)
{
scanf("%s",&w);
insert(w);
}
AC();
scanf("%s",s);
int ans=match(s);
printf("%d\n",ans);
}
return 0;
}