题意:
有n(<=10000个模式串(length<=50),现在有一个串(<=1000000)..问其中出现了多少个模式串.
题解:
裸AC自动机....空间限制略恶心..直接用指针会好一些....更新模板...
Program:
#include<iostream>
#include<cstring>
#include<cstdio>
#include<queue>
#define ll long long
#define MAXNODE 242005
using namespace std;
class Ac_Atomation
{
private:
struct node
{
int son[26],fail,w;
}T[MAXNODE];
int num;
queue<int> Q;
public:
void clear()
{
memset(T,0,sizeof(T)),num=0;
}
void insert(char *s)
{
int i,h=0,x,len=strlen(s);
for (i=0;i<len;i++)
{
x=s[i]-'a';
if (!T[h].son[x]) T[h].son[x]=++num;
h=T[h].son[x];
}
T[h].w++;
}
void built()
{
int i,h,x;
while (Q.size()) Q.pop();
for (i=0;i<26;i++)
if (T[0].son[i]) Q.push(T[0].son[i]);
while (Q.size())
{
h=Q.front(),Q.pop();
for (i=0;i<26;i++)
{
for (x=T[h].fail;x && !T[x].son[i];x=T[x].fail);
T[T[h].son[i]].fail=T[x].son[i];
if (!T[h].son[i])
T[h].son[i]=T[x].son[i];
else
Q.push(T[h].son[i]);
}
}
}
int exit(char *s,int n)
{
int i,h=0,p,x,ans=0,len=strlen(s);
char c;
for (i=0;i<len;i++)
{
x=s[i]-'a';
h=T[h].son[x];
for (p=h;p;p=T[p].fail)
if (T[p].w)
ans+=T[p].w,T[p].w=0;
}
return ans;
}
}T;
char s[1000005];
int main()
{
int cases,i,n;
scanf("%d",&cases);
while (cases--)
{
T.clear();
scanf("%d",&n);
while (n--)
scanf("%s",s),T.insert(s);
T.built();
scanf("%s",s);
printf("%d\n",T.exit(s,n));
}
return 0;
}