这个和bzoj同名题不同,有多个匹配串
可是思路是同样的,写个AC自动机,一样是开两个栈,一个存字符,一个存当前点在trie树上的位置,而后若是到了某个匹配串的末尾,则弹栈ios
#include<iostream> #include<cstdio> #include<cstring> #include<queue> using namespace std; const int N=100005; int n,t[N],top; char a[N],b[N],s[N]; struct AC { int tot,c[N][27],f[N],l[N]; void ins(char s[]) { int len=strlen(s),nw=0; for(int i=0;i<len;i++) { if(!c[nw][s[i]-'a']) c[nw][s[i]-'a']=++tot; nw=c[nw][s[i]-'a']; } l[nw]=len; } void build() { queue<int>q; for(int i=0;i<26;i++) if(c[0][i])//!!!!!!!!!!!!!!!!!!!!!!!!!!! f[c[0][i]]=0,q.push(c[0][i]); while(!q.empty()) { int u=q.front(); q.pop(); for(int i=0;i<26;i++) { if(c[u][i]) f[c[u][i]]=c[f[u]][i],q.push(c[u][i]); else c[u][i]=c[f[u]][i]; } } } void wk(char a[]) { int len=strlen(a),nw=0; for(int i=0;i<len;i++) { nw=c[nw][a[i]-'a']; s[++top]=a[i],t[top]=nw; if(l[nw]) top-=l[nw],nw=t[top]; } for(int i=1;i<=top;i++) putchar(s[i]); } }ac; int main() { scanf("%s%d",a,&n); for(int i=1;i<=n;i++) { scanf("%s",b); ac.ins(b); } ac.build(); ac.wk(a); return 0; }