題目連接:https://codeforces.com/contest/670/problem/E
html
題意:c++
給出一個已經匹配的括號串,給出起始的光標位置(光標老是指向某個括號)。spa
有以下操做:code
一、往左移動一下光標;htm
二、往左移動一下光標;blog
三、刪除當前光標指向的括號,以及和它匹配的那個括號,以及這兩個括號之間的全部括號。ci
要求你給出在作完全部操做後的括號串。get
題解:it
用對頂棧進行模擬。因爲刪除是不可逆的,所以刪除的總時間複雜度爲 $O(n)$,所以全部 $m$ 次操做的總時間複雜度爲 $O(n+m)$。class
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(); }