题意:
从文本串上删除一些字符串 每次优先删除从左边开始第一个满足的,删除后剩下的串连在一起重复删除步骤直到不能删。
题解:
A C AC AC自动机 + 栈
用要删除的串构建 A C AC AC自动机,让文本串在 A C AC AC自动机上匹配,再用一个栈记录经过的字符,如果匹配成功了,说明文本串包含了要删除的串,我们将 t o p top top指针前移 l e n len len位即可。
A C AC AC代码:
#include<bits/stdc++.h>
using namespace std;
const int MAXN = 1e6+50;
char s[MAXN],ss[MAXN];
int nxt[MAXN][26],fail[MAXN],len[MAXN],vis[MAXN];
int sta[MAXN],id[MAXN],sz;
inline void Insert(char *s){
int root = 0,length = strlen(s);
for(int i=0;i<length;i++){
if(!nxt[root][s[i]-'a']) nxt[root][s[i]-'a'] = ++sz;
root = nxt[root][s[i]-'a'];
}
len[root] = length;
}
inline void Build(){
queue<int> que;
for(int i=0;i<26;i++)
if(nxt[0][i])
que.push(nxt[0][i]);
while(!que.empty()){
int u = que.front(); que.pop();
for(int i=0;i<26;i++){
if(nxt[u][i]) fail[nxt[u][i]] = nxt[fail[u]][i],que.push(nxt[u][i]);
else nxt[u][i] = nxt[fail[u]][i];
}
}
}
int main(){
scanf("%s",s);
scanf("%s",ss);
Insert(ss);
Build();
int n = strlen(s),root = 0,top = 0;
for(int i=0;i<n;i++){
id[i] = root = nxt[root][s[i]-'a'];
sta[++top] = i;
if(len[root]){
top -= len[root];
root = id[sta[top]];
}
}
for(int i=1;i<=top;i++) putchar(s[sta[i]]);
puts("");
return 0;
}