题目:http://acm.hdu.edu.cn/showproblem.php?pid=2222
分析:
AC自动机模板题
代码:
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int tmax=10005*30;
const int tmax2=1e6+5;
int n,ch[tmax][30],num,f[tmax],val[tmax],ans,last[tmax];
bool vis[tmax];
queue<int> Q;
void insert(char *s)
{
int i,len=strlen(s),u=0,id;
for(i=0;i<len;i++)
{
id=s[i]-'a';
if(ch[u][id]==0)
ch[u][id]=++num;
u=ch[u][id];
}
val[u]++;
return;
}
void getfail()
{
for(int c=0;c<26;c++)
{
int u=ch[0][c];
if(u) Q.push(u);
}
while(!Q.empty())
{
int x=Q.front();
Q.pop();
for(int c=0;c<26;c++)
{
int u=ch[x][c];
if(!u)
{
ch[x][c]=ch[f[x]][c];
continue;
}
Q.push(u);
int v=f[x];
while(v&&!ch[v][c]) v=f[v];
f[u]=ch[v][c];
last[u]=val[f[u]]?f[u]:last[f[u]]; //last[j]:表示j节点沿着失配指针往回走时
//遇到的下一个单词节点编号
}
}
return;
}
void find(char *s)
{
int len=strlen(s),j=0,k,id;
for(int i=0;i<len;i++)
{
id=s[i]-'a';
j=ch[j][id];
k=j;
if(!vis[k]) ans+=val[k];
vis[k]=true;
while(last[k])
{
k=last[k];
if(!vis[k]) ans+=val[k];
vis[k]=true;
}
}
return;
}
int main()
{
int T,i;
char tmp[tmax2];
cin>>T;
while(T--)
{
ans=num=0;
memset(ch,0,sizeof(ch));
memset(f,0,sizeof(f));
memset(vis,0,sizeof(vis));
memset(val,0,sizeof(val));
memset(last,0,sizeof(last));
scanf("%d",&n);
for(i=1;i<=n;i++)
{
scanf("%s",tmp);
insert(tmp);
}
getfail();
scanf("%s",tmp);
find(tmp);
printf("%d\n",ans);
}
return 0;
}