這個和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; }