Codeforces 670E (Correct Bracket Sequence Editor)

tags:[双向链表]
题解:
用pre[i]记录第i个括号的上一个括号位置,nxt[i]记录i的下一个括号位置
用cp[i]记录下与第i个括号相匹配的括号的位置。
对于L,R操作,直接p=pre[p],p=nxt[p]就行了
对于D操作,我们分类考虑
1) s[p]='(', 我们找到与第p个括号的cp。
那么区间[ p,cp[p] ]中所有的括号就会被放逐!
这个时候我们来维护一下,pre,nxt数组
将pre[p]的下一个元素,修改成:nxt[cp[p]]。
将nxt[cp[p]]的上一个元素,修改成:pre[p]。
2) s[p]=')', 同理。[厚颜无耻.jpg]

code:

#include <iostream>
#include <cstdio>
using namespace std;
const int NICO = 500000 + 10;
int n, m, p;
int l[NICO], pre[NICO], nxt[NICO], cp[NICO], top;
int vis[NICO];
char s[NICO], s1[NICO];
int main()
{
    scanf("%d %d %d", &n, &m, &p);
    scanf("%s %s", s+1, s1+1);
    for(int i=1;i<=n;i++)
    {
        pre[i] = i-1;
        nxt[i] = i+1;
        if(s[i] == '(')
        {
            l[++top] = i;
        } else {
            cp[i] = l[top];
            cp[l[top]] = i;
            top --;
        }
    }
    for(int i=1;i<=m;i++)
    {
        if(s1[i] == 'L')
        {
            p = pre[p];
        } 
        if(s1[i] == 'R')
        {
            p = nxt[p];
        }
        if(s1[i] == 'D')
        {
            int x, y;
            if(s[p] == '(')
            {
                y = nxt[cp[p]];
                x = pre[p];
            } else {
                y = nxt[p];
                x = pre[cp[p]];
            }
            pre[y] = x; 
            nxt[x] = y;
            p = (y>=n)?x:y;
            vis[x+1]+=1, vis[y-1]-=1;
        }
    }
    int sum = 0;
    for(int i=1;i<=n;i++)
    {
        sum += vis[i];
        if(!sum && !vis[i]) printf("%c", s[i]);
    }
    printf("
");
}

  

原文地址:https://www.cnblogs.com/RUSH-D-CAT/p/6414859.html