Codeforces 670E - Correct Bracket Sequence Editor - [对顶栈]

题目链接:https://codeforces.com/contest/670/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();
}

 

posted @ 2019-03-11 16:34  Dilthey  阅读(227)  评论(0编辑  收藏  举报