题意:
多模式串匹配.
思路:
AC自动机,注意回溯.
优化fail建立过程.
#include<cstring>
#include<cstdio>
#include<algorithm>
using namespace std;
const int MAXN = 240055;
const int MAXL = 1000005;
struct AC_machine
{
int fail[MAXN];
int sz;
int ch[MAXN][26];
int ID[128];
int n;
char str[MAXL];
int Q[MAXN];
int v[MAXN];
void Init()
{
sz = 1;
memset(ch[0],0,sizeof(ch[0]));
memset(v,0,sizeof(v));
fail[0] = 0;
for(int i=0;i<26;i++) ID[i+'a'] = i;
}
void Insert(char s[])
{
int cur = 0;
for(int i=0;s[i];i++)
{
int c = ID[s[i]];
if(!ch[cur][c])
{
memset(ch[sz],0,sizeof(ch[sz]));
ch[cur][c] = sz++;
}
cur = ch[cur][c];
}
v[cur]++;
}
void Input()
{
scanf("%d",&n);
char s[55];
for(int i=0;i<n;i++)
{
scanf("%s",s);
Insert(s);
}
scanf("%s",str);
}
void Build()
{
int st = 0, en = 0;
for(int i=0;i<26;i++)
{
if(ch[0][i])
{
fail[ch[0][i]] = 0;
Q[en++] = ch[0][i];
}
}
while(st!=en)
{
int cur = Q[st++];
for(int i=0;i<26;i++)
{
int &v = ch[cur][i];
if(v)
{
Q[en++] = v;
fail[v] = ch[fail[cur]][i];
}
else
{
v = ch[fail[cur]][i];//优化
}
}
}
}
void solve()
{
int ans = 0,j = 0,tmp;
for(int i=0;str[i];i++)
{
if(ch[j][ID[str[i]]]) j = ch[j][ID[str[i]]];
else
{
while(j && !ch[j][ID[str[i]]]) j = fail[j];
if(ch[j][ID[str[i]]]) j = ch[j][ID[str[i]]];
}
tmp = j;
while(tmp && v[tmp])
{
ans += v[tmp];
v[tmp] = 0;
tmp = fail[tmp];
}
}
printf("%d\n",ans);
}
} AC;
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
AC.Init();
AC.Input();
AC.Build();
AC.solve();
}
}