bzoj 2329 [HNOI2011]括号修复 splay
2016-12-29 09:15
441 查看
区间赋值,区间翻转,区间反转,也就splay能干这些事吧。。。
维护一个区间最小值low,区间最大值up,区间和sum,然后一段区间的答案是
(−low[x]+1)/2+(sum[x]+(−low[x]+1)/2∗2)/2
再打一坨标记就行了,注意标记重叠
维护一个区间最小值low,区间最大值up,区间和sum,然后一段区间的答案是
(−low[x]+1)/2+(sum[x]+(−low[x]+1)/2∗2)/2
再打一坨标记就行了,注意标记重叠
#include <bits/stdc++.h> using namespace std; #define N 110000 #define which(x) (ch[fa[x]][1]==x) int n,m,root,cnt; char s ; int val ,size ,rev ,inv ,rep ; int ch [2],fa ,up ,low ,sum ; void pushup(int x) { size[x]=size[ch[x][0]]+size[ch[x][1]]+1; sum[x]=sum[ch[x][0]]+sum[ch[x][1]]+val[x]; up[x]=max(up[ch[x][0]],up[ch[x][1]]+sum[ch[x][0]]+val[x]); low[x]=min(low[ch[x][0]],low[ch[x][1]]+sum[ch[x][0]]+val[x]); } void invert(int x) { val[x]=-val[x],inv[x]^=1; sum[x]=-sum[x]; swap(low[x],up[x]); up[x]=-up[x];low[x]=-low[x]; } void replace(int x,int v) { inv[x]=0; if(v==1) { rep[x]=val[x]=1;sum[x]=size[x]; up[x]=size[x];low[x]=0; } else { rep[x]=val[x]=-1;sum[x]=-size[x]; up[x]=0;low[x]=-size[x]; } } void reverse(int x) { rev[x]^=1; swap(low[x],up[x]); up[x]=sum[x]-up[x]; low[x]=sum[x]-low[x]; } void pushdown(int x) { if(rev[x]) { swap(ch[x][0],ch[x][1]); reverse(ch[x][0]);reverse(ch[x][1]); rev[x]=0; } if(rep[x]) { replace(ch[x][0],rep[x]); replace(ch[x][1],rep[x]); rep[x]=0; } if(inv[x]) { invert(ch[x][0]);invert(ch[x][1]); inv[x]=0; } } void down(int x) { if(fa[x])down(fa[x]); pushdown(x); } int build(int l,int r) { if(l>r)return 0; int mid=(l+r)>>1,ret=++cnt; val[ret]=(s[mid]=='(' ? 1:-1); ch[ret][0]=build(l,mid-1); ch[ret][1]=build(mid+1,r); fa[ch[ret][0]]=fa[ch[ret][1]]=ret; pushup(ret); return ret; } int find(int x,int K) { pushdown(x); if(K==size[ch[x][0]]+1)return x; if(K<=size[ch[x][0]]) return find(ch[x][0],K); return find(ch[x][1],K-size[ch[x][0]]-1); } void rotate(int x) { int y=fa[x],k=which(x); ch[y][k]=ch[x][k^1]; ch[x][k^1]=y; ch[fa[y]][which(y)]=x; fa[x]=fa[y];fa[y]=x; fa[ch[y][k]]=y; pushup(y);pushup(x); } void splay(int x,int tar) { down(x); while(fa[x]!=tar) { int y=fa[x]; if(fa[y]==tar)rotate(x); else { if(which(x)^which(y))rotate(x); else rotate(y); rotate(x); } } if(!tar)root=x; } int main() { scanf("%d%d%s",&n,&m,s+1); root=build(0,n+1); for(int l,r;m--;) { scanf("%s%d%d",s+1,&l,&r); int pl=find(root,l),pr=find(root,r+2); splay(pl,0);splay(pr,root); int x=ch[pr][0]; if(s[1]=='R') { scanf("%s",s+1); replace(x,s[1]=='(' ? 1:-1); } else if(s[1]=='S')reverse(x); else if(s[1]=='I')invert(x); else { int t=(-low[x]+1)/2; printf("%d\n",t+(sum[x]+t*2)/2); } pushup(pr);pushup(pl); } return 0; }
相关文章推荐
- 【bzoj2329】[HNOI2011]括号修复 splay
- BZOJ 2329 HNOI 2011 括号修复 Splay维护最大连续子段和
- bzoj2329 [HNOI2011]括号修复(splay)
- BZOJ 2329 HNOI2011 括号修复 Splay
- BZOJ2329 HNOI2011 括号修复 splay+贪心
- 【bzoj2329】[HNOI2011]括号修复 Splay
- [BZOJ2329][HNOI2011]括号修复-splay
- BZOJ 2329: [HNOI2011]括号修复 [splay 括号]
- bzoj 2329: [HNOI2011]括号修复 splay
- 【BZOJ2329/2209】[HNOI2011]括号修复/[Jsoi2011]括号序列 Splay
- BZOJ 2329: [HNOI2011]括号修复( splay )
- [HNOI2011][bzoj 2329] 括号修复 [splay+前缀和]
- 【BZOJ-2329】[HNOI2011] 括号修复
- BZOJ2329: [HNOI2011]括号修复
- bzoj2329 [HNOI2011]括号修复
- Bzoj2329: [HNOI2011]括号修复
- BZOJ2329 [HNOI2011]括号修复
- bzoj2329 [HNOI2011]括号修复
- ●BZOJ 2329 [HNOI2011]括号修复.cpp
- 【bzoj2329】[HNOI2011]括号修复