Codeforces 670E - Correct Bracket Sequence Editor - [對頂棧]

題目連接: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();
}
相關文章
相關標籤/搜索