题意:一串括号序列,有一个移动光标,给出三种操作,‘L’:将光标左移,‘R’:将光标右移,‘D’删除光标所在括号及其对应括号之间的序列,并将括号移动到删除序列的右端,若右端不存在,则移动到左端。输出最后序列。
题解:模拟双向链表
用
l
e
[
]
le[]
le[]记录当前括号的左端是哪一个,
r
i
[
]
ri[]
ri[]记录右端,
p
a
[
]
pa[]
pa[]记录与之匹配的括号下标,用stack模拟一下。
因为最后要输出最终序列,用 s t st st记录一下起始下标。
#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
#include<cstdio>
#include<string>
#include<cstring>
#include<algorithm>
#include<queue>
#include<stack>
#include<cmath>
#include<vector>
#include<fstream>
#include<set>
#include<map>
#include<sstream>
#include<iomanip>
#define ll long long
using namespace std;
const int maxn = 5e5 + 5;
int n, m, p, le[maxn], ri[maxn], pa[maxn];
char s[maxn], op[maxn];
stack<int> q;
int main() {
scanf("%d%d%d%s%s", &n, &m, &p, s + 1, op);
for (int i = 1; i <= n; i++) {
le[i] = i - 1;
ri[i] = i + 1;
if (s[i] == '(') {
q.push(i);
}
else {
pa[q.top()] = i;
pa[i] = q.top();
q.pop();
}
}
int st = 1;
for (int i = 0; i < m; i++) {
if (op[i] == 'L') p = le[p];
else if (op[i] == 'R') p = ri[p];
else {
int l = min(p, pa[p]);
int r = max(p, pa[p]);
if (ri[r] != n + 1) p = ri[r];
else p = le[l];
le[ri[r]] = le[l];
ri[le[l]] = ri[r];
if (l == st) st = ri[r];
}
}
for (int i = st; i != n + 1; i = ri[i]) printf("%c", s[i]);
return 0;
}