题解:CF670E Correct Bracket Sequence Editor
首先我们用 map 和栈把左右括号匹配好,然后我们发现删除和左右移动的操作和双端链表非常契合,那么我们用双端链表模拟一下即可。
具体的:
- 题中的
L就将 p 向左移动。 - 题中的
R就将 p 向右移动。 - 题中的
D就将 p 和 map_p 中较大的一位的后一位,p 和 map_p 中较小的一位的前一位连到一起,然后更新并判断 p 有没有出界就可以了。
代码:
#include<bits/stdc++.h>
using namespace std;
int n,m,p,idx;
struct node{
char s;
int fr,be;//front,behind
}lik[500010];
map<int,int>mp;
stack<int>st;
int main(){
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
cin>>n>>m>>p;
lik[0].be=1;
for(int i=1;i<=n;i++){
cin>>lik[++idx].s;
lik[idx].fr=idx-1;
lik[idx].be=idx+1;
}
lik[idx+1].fr=n;
lik[idx+1].be=-1;
for(int i=1;i<=idx;i++){
if(lik[i].s=='('){
st.push(i);
}else{
if(lik[i].s==')'&&!st.empty()){
mp[st.top()]=i;
mp[i]=st.top();
st.pop();
}
}
}
while(m--){
char x;
cin>>x;
if(x=='L'){
p=lik[p].fr;
}else if(x=='R'){
p=lik[p].be;
}else{
int x=lik[max(mp[p],p)].be;
lik[lik[max(mp[p],p)].be].fr=lik[min(mp[p],p)].fr;
lik[lik[min(mp[p],p)].fr].be=lik[max(mp[p],p)].be;
p=x;
if(p>n){
p=lik[p].fr;
}
}
}
if(p){
for(int i=0;i!=-1;i=lik[i].be){
if(!i){
continue;
}
if(lik[i].be==-1){
break;
}
cout<<lik[i].s;
}
}
return 0;
}