【题意】一个括号序列,你有以下三种操作:"L"光标左移;"R"光标右移;"D"删掉这个括号以及和它对应的括号之间的所有括号,并且把光标移动到被删后右边的那个括号上。如果没有了,就移动到串的末尾。现在给你原括号序列和操作,求最终结果!

【分析】由于操作最多有50万个,那么简单想一下用链表来暴力模拟都是能过得去的。那么,我在这里用了类似于跳转链表来模拟这个过程!但是这里我并不是一个一个的跳转的,而是预处理了最大的括号匹配,直接跳转到可以到达的最大位置,这样就更快的完成删除这个过程了!具体实现,见下面的代码!

【AC代码】

#include <stdio.h>
#include <cstring>
#include <iostream>
using namespace std;
const int maxn = 500010;
char s[maxn],q[maxn];
int l[maxn],r[maxn],pos[maxn];//l,r分别来表示左移和右移
int S[maxn];
int main(){
    int n,m,p,top=0;
    cin>>n>>m>>p;
    cin>>s>>q;
    //INIT.
    for(int i=1; i<=n; i++){
        l[i]=i-1,r[i]=i==n?0:i+1;
        if(s[i-1]=='('){
                S[++top] = i;
           }else{
                pos[S[top]] = i;//记录左括号对应的右括号位置
                pos[i] = S[top--];//记录右括号对应的左括号
           }
    }
    //UPdate And Query.
    for(int i=1; i<=m; i++){
        if(q[i-1]=='L') p = l[p];
        else if(q[i-1]=='R') p = r[p];
        else{
            if(s[p-1]==')') p = pos[p];//向左的话就要直接访问pos[p],向右则不用转换!
            //合并区间
            l[r[pos[p]]] = l[p];//清除匹配的括号-->
            r[l[p]] = r[pos[p]];//清除匹配的括号<--
            p = r[pos[p]]==0?l[p]:r[pos[p]];
        }
    }
    while(l[p]) p=l[p];//找到最左边的括号的位置
    while(p){
        cout<<s[p-1]<<"";
        p = r[p];
    }
    return 0;
}