https://www.luogu.org/problem/show?pid=3121
这题嘛。。。AC自动机
我们在匹配的时候可以开一个栈,一开始栈内为空,匹配时依次加入字母的位置,当匹配完成时把这个单词弹出继续操作就好了
其他没啥变化
具体看这段代码啦
inline void getans(int l){
int now=0;
for(int i=1;i<=l;i++){
now=p[now][s[i]-'a'];
pr[++sum]=now;rp[sum]=i;
if(b[now]){//以下下弹栈操作
sum-=b[now];
now=pr[sum];
}
}
}
好像被数据坑了,据lc233说,按照一开始的bfs求fail写法会超时。。。
所以换了一个模板。。。
不多说,上代码吧
#include<bits/stdc++.h>
using namespace std;
char s[100001],c[100001];
int n,np=0,q[100001],p[100001][26],fail[100001];
int rp[100001],pr[100001],b[100001],sum=0;
inline void insert(){
int now=0,l=strlen(c+1);
for(int i=1;i<=l;i++){
int t=c[i]-'a';
if(!p[now][t])p[now][t]=++np;
now=p[now][t];
}
b[now]=l;
}
inline void bfs(){
int l,r;l=r=0;
for(int i=0;i<26;i++)if(p[0][i])q[++r]=p[0][i];
while(l<r){
l++;
int t=q[l];
for(int i=0;i<26;i++)if(!p[t][i])p[t][i]=p[fail[t]][i];
else{
q[++r]=p[t][i];
fail[p[t][i]]=p[fail[t]][i];
}
}
}
inline void getans(int l){
int now=0;
for(int i=1;i<=l;i++){
now=p[now][s[i]-'a'];
pr[++sum]=now;rp[sum]=i;
if(b[now]){
sum-=b[now];
now=pr[sum];
}
}
}
int main()
{
scanf("%s",s+1);
scanf("%d",&n);
for(int i=1;i<=n;i++)scanf("%s",c+1),insert();
bfs();
int l=strlen(s+1);getans(l);
for(int i=1;i<=sum;i++)printf("%c",s[rp[i]]);
return 0;
}