题目链接:https://codeforces.com/gym/240084/problem/E
题意:
给出一个已经匹配的括号串,给出起始的光标位置(光标总是指向某个括号)。
有如下操作:
1、往左移动一下光标;
2、往左移动一下光标;
3、删除当前光标指向的括号,以及和它匹配的那个括号,以及这两个括号之间的所有括号。
要求你给出在做完所有操作后的括号串。
题解:
用对顶栈进行模拟。由于删除是不可逆的,因此删除的总时间复杂度为 $O(n)$,因此所有 $m$ 次操作的总时间复杂度为 $O(n+m)$。
AC代码:
#include<bits/stdc++.h> using namespace std; const int maxn=5e5+5; int n,m,p; char str[maxn],op[maxn]; int bro[maxn]; vector<int> s,t; void print() { for(int i=0;i<s.size();i++) printf("%c",str[s[i]]); for(int i=t.size()-1;i>=0;i--) printf("%c",str[t[i]]); printf("\n"); } int main() { cin>>n>>m>>p; scanf("%s",str+1); for(int i=1;i<=p;i++) s.push_back(i); for(int i=n;i>p;i--) t.push_back(i); stack<int> S; for(int i=1;i<=n;i++) { if(str[i]=='(') S.push(i); if(str[i]==')') bro[S.top()]=i, bro[i]=S.top(), S.pop(); } scanf("%s",op+1); for(int i=1;i<=m;i++) { if(op[i]=='L') t.push_back(s.back()), s.pop_back(); if(op[i]=='R') s.push_back(t.back()), t.pop_back(); if(op[i]=='D') { p=s.back(); if(p<bro[p]) { s.pop_back(); while(t.size() && t.back()<=bro[p]) t.pop_back(); } if(bro[p]<p) { while(s.size() && s.back()>=bro[p]) s.pop_back(); } if(t.size()) s.push_back(t.back()), t.pop_back(); } } print(); }