传送门
洛谷的标签和题解都说这题需要用栈,但其实用一个记忆数组pre+string类的earse函数就够了.只需要每次跑到可以删除的状态,直接删然后跑回pre[i-len]就可以了.
代码
#define LL long long
#define pq priority_queue
#define ULL unsigned long long
#define pb push_back
#define mem(a,x) memset(a,x,sizeof a)
#define pii pair<int,int>
#define fir(i,a,b) for(int i=a;i<=(int)b;++i)
#define afir(i,a,b) for(int i=(int)a;i>=b;--i)
#define ft first
#define vi vector<int>
#define sd second
#define ALL(a) a.begin(),a.end()
#define bug puts("-------")
#define mpr(a,b) make_pair(a,b)
#include <bits/stdc++.h>
using namespace std;
const int N = 4e5+10;
inline int read(){
int x = 0,f=1;char ch = getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch<='9'&&ch>='0'){x=x*10+ch-'0';ch=getchar();}
return x*f;
}
namespace Auto{
int trie[26][N],fail[N],fa[N],tot,dep[N],p,ed[N],tt[26][N],pre[N];
vector<pii> vec;
void ins(string s){
p = 0;
int dp = 1;
for(auto x:s){
int ch = x - 'a';
if(!trie[ch][p]) fa[++tot] = p,dep[tot] = dp,trie[ch][p] = tot,tt[ch][p] = tot;
p = trie[ch][p];
dp++;
}
ed[p] = 1;
}
void bfs(){
queue<int> q;
fir(i,0,25) if(trie[i][0]) q.push(trie[i][0]);
while(q.size()){
int p = q.front();q.pop();
fir(i,0,25){
int fl = fail[p];
if(trie[i][p]) fail[trie[i][p]] = trie[i][fl],q.push(trie[i][p]);
else trie[i][p] = trie[i][fl];
}
}
}
void dfs(string &s){
p = 0;
fir(i,0,(int)s.size()-1){
char x = s[i];
int ch = x - 'a';
p = trie[ch][p];
if(ed[p]){
int len = dep[p];
s.erase(i-len+1,len);
p = pre[i-len];
i = i-len;
pre[i] = p;
continue;
}
pre[i] = p;
}
}
}
using namespace Auto;
int main(){
ios::sync_with_stdio(false);
cin.tie(0);
string str,s;
cin >> str;
int n;
cin >> n;
fir(i,1,n){
cin >> s;
ins(s);
}
bfs();
dfs(str);
cout << str << "\n";
return 0;
}