題目連接:https://codeforces.com/contest/670/problem/Ehtml
題意:c++
給出一個已經匹配的括號串,給出起始的光標位置(光標老是指向某個括號)。ui
有以下操做:spa
一、往左移動一下光標;code
二、往左移動一下光標;htm
三、刪除當前光標指向的括號,以及和它匹配的那個括號,以及這兩個括號之間的全部括號。blog
要求你給出在作完全部操做後的括號串。ci
題解:get
用線段樹維護,每一個括號是否存在,存在記爲 $1$,被刪掉了記爲 $0$。it
而後咱們只須要實現:①區間求和、②區間賦值、③根據 $k$ 求最小的 $x$ 知足在區間 $[1,x]$ 上求和正好等於 $k$。
移動光標能夠經過①和③來完成;刪除能夠經過②來刪除,刪除完以後的光標移動依然能夠靠①③完成。
時間複雜度是 $O(n + m \log n)$,分別是建樹的 $O(n)$ 以及 $m$ 次操做的時間複雜度。
AC代碼:
#include<bits/stdc++.h> using namespace std; const int maxn=5e5+5; int n,m,p; char s[maxn]; char op[maxn]; #define ls (rt<<1) #define rs (rt<<1|1) struct Node{ int l,r; int val; bool del; void update() { val=0, del=1; } }o[maxn<<2]; void pushdown(int rt) { if(o[rt].del) { o[ls].update(); o[rs].update(); o[rt].del=0; } } inline void pushup(int rt) { o[rt].val=o[ls].val+o[rs].val; } void build(int rt,int l,int r) { o[rt].l=l, o[rt].r=r; o[rt].del=0; if(l==r) { o[rt].val=1; return; } int mid=(l+r)>>1; build(ls,l,mid); build(rs,mid+1,r); pushup(rt); } void del(int rt,int st,int ed) { if(st<=o[rt].l && o[rt].r<=ed) { o[rt].update(); return; } pushdown(rt); int mid=(o[rt].l+o[rt].r)>>1; if(st<=mid) del(ls,st,ed); if(mid<ed) del(rs,st,ed); pushup(rt); } int sum(int rt,int st,int ed) { if(st>ed) return 0; if(st<=o[rt].l && o[rt].r<=ed) return o[rt].val; pushdown(rt); int mid=(o[rt].l+o[rt].r)>>1; int res=0; if(st<=mid) res+=sum(ls,st,ed); if(mid<ed) res+=sum(rs,st,ed); pushup(rt); return res; } int idx(int rt,int k) { if(o[rt].l==o[rt].r) return 1; pushdown(rt); if(o[ls].val>=k) return idx(ls,k); else return (o[ls].r-o[ls].l+1)+idx(rs,k-o[ls].val); } stack<int> S; int bro[maxn]; int main() { cin>>n>>m>>p; scanf("%s",s+1); for(int i=1;i<=n;i++) { if(s[i]=='(') S.push(i); if(s[i]==')') bro[S.top()]=i, bro[i]=S.top(), S.pop(); } scanf("%s",op+1); build(1,1,n); for(int q=1;q<=m;q++) { if(op[q]=='L') { p=idx(1,sum(1,1,p)-1); } if(op[q]=='R') { p=idx(1,sum(1,1,p)+1); } if(op[q]=='D') { int st=min(p,bro[p]); int ed=max(p,bro[p]); del(1,st,ed); if(sum(1,ed+1,n)>0) p=idx(1,sum(1,1,ed)+1); else p=idx(1,sum(1,1,st-1)); } } for(int i=1;i<=n;i++) { if(sum(1,i,i)>0) printf("%c",s[i]); } }