同3942,把KMP换成AC自动机。
开一个栈,记录一下每个位置匹配到哪个节点,如果是单词节点,那么弹出对应长度的字符串。
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<algorithm>
#include<iostream>
#define maxn 110010
using namespace std;
int ch[maxn][26],fail[maxn],q[maxn],w[maxn],dep[maxn];
char s[maxn],st[maxn],s1[maxn];
int n,m,tot,top,root;
int newnode()
{
tot++;
for (int i=0;i<26;i++) ch[tot][i]=-1;
return tot;
}
void insert()
{
int n=strlen(s1+1),x=root;
for (int i=1;i<=n;i++)
{
if (ch[x][s1[i]-'a']==-1) ch[x][s1[i]-'a']=newnode();
x=ch[x][s1[i]-'a'];
}
dep[x]=n;
}
void build_fail()
{
int l=0,r=0;
fail[root]=root;
for (int i=0;i<26;i++)
if (ch[root][i]==-1) ch[root][i]=root;
else
{
fail[ch[root][i]]=root;
q[++r]=ch[root][i];
}
while (l<r)
{
int x=q[++l];
for (int i=0;i<26;i++)
if (ch[x][i]==-1) ch[x][i]=ch[fail[x]][i];
else
{
fail[ch[x][i]]=ch[fail[x]][i];
q[++r]=ch[x][i];
}
}
}
int main()
{
//freopen("data.in","r",stdin);
//freopen("data.out","w",stdout);
scanf("%s",s+1);
tot=0;root=newnode();
scanf("%d",&n);
for (int i=1;i<=n;i++)
{
scanf("%s",s1+1);
insert();
}
build_fail();
int x=root,len=strlen(s+1);w[0]=root;
for (int i=1;i<=len;i++)
{
st[++top]=s[i];
x=ch[x][s[i]-'a'];w[top]=x;
if (dep[x]) top-=dep[x],x=w[top];
}
for (int i=1;i<=top;i++) printf("%c",st[i]);printf("\n");
return 0;
}