Gym 240084E - Correct Bracket Sequence Editor - [线段树]
Posted dilthey
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Gym 240084E - Correct Bracket Sequence Editor - [线段树]相关的知识,希望对你有一定的参考价值。
题目链接:https://codeforces.com/gym/240084/problem/E
题意:
给出一个已经匹配的括号串,给出起始的光标位置(光标总是指向某个括号)。
有如下操作:
1、往左移动一下光标;
2、往左移动一下光标;
3、删除当前光标指向的括号,以及和它匹配的那个括号,以及这两个括号之间的所有括号。
要求你给出在做完所有操作后的括号串。
题解:
用线段树维护,每个括号是否存在,存在记为 $1$,被删掉了记为 $0$。
然后我们只需要实现:①区间求和、②区间赋值、③根据 $k$ 求最小的 $x$ 满足在区间 $[1,x]$ 上求和正好等于 $k$。
移动光标可以通过①和③来完成;删除可以通过②来删除,删除完之后的光标移动依然可以靠①③完成。
时间复杂度是 $O(n + m log 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]); } }
以上是关于Gym 240084E - Correct Bracket Sequence Editor - [线段树]的主要内容,如果未能解决你的问题,请参考以下文章
手机为啥一直弹出please and or correct UmengIntentService