分享web开发知识

注册/登录|最近发布|今日推荐

主页 IT知识网页技术软件开发前端开发代码编程运营维护技术分享教程案例
当前位置:首页 > 教程案例

【BZOJ2329/2209】[HNOI2011]括号修复/[Jsoi2011]括号序列 Splay

发布时间:2023-09-06 01:28责任编辑:白小东关键词:暂无标签

【BZOJ2329/2209】[HNOI2011]括号修复/[Jsoi2011]括号序列

题解:我们的Splay每个节点维护如下东西:左边有多少多余的右括号,右边有多少多余的左括号,同时为了反转操作,还要维护左边有多少多余的左括号,右边有多少多余的右括号(如果一个右括号匹配一个左括号的话)。然后xjb维护一番即可。。。

#include <cstdio>#include <cstring>#include <iostream>using namespace std;const int maxn=100010;int n,m,rt;struct node{int v,f[2][2],ch[2],fa,siz,tag;bool r1,r2;}s[maxn];char str[maxn];//‘(‘->0 ‘)‘->1 r1->反 r2->翻inline int ab(const int &a) {return a>0?a:0;}inline void pushup(int x){int l=s[x].ch[0],r=s[x].ch[1];s[x].siz=s[l].siz+s[r].siz+1;s[x].f[0][0]=s[l].f[0][0]+ab(s[r].f[0][0]-s[x].v-s[l].f[1][1]);s[x].f[1][1]=s[r].f[1][1]+ab(s[l].f[1][1]+s[x].v-s[r].f[0][0]);s[x].f[0][1]=s[l].f[0][1]+ab(s[r].f[0][1]+s[x].v-s[l].f[1][0]);s[x].f[1][0]=s[r].f[1][0]+ab(s[l].f[1][0]-s[x].v-s[r].f[0][1]);}inline void rev1(int x){s[x].tag=-s[x].tag,s[x].v=-s[x].v,s[x].r1^=1,swap(s[x].f[0][0],s[x].f[0][1]),swap(s[x].f[1][0],s[x].f[1][1]);}inline void rev2(int x){s[x].r2^=1,swap(s[x].ch[0],s[x].ch[1]),swap(s[x].f[0][0],s[x].f[1][0]),swap(s[x].f[0][1],s[x].f[1][1]);}inline void cover(int x,int y){s[x].tag=s[x].v=y,s[x].f[0][y>0]=s[x].f[1][y>0]=s[x].siz,s[x].f[0][y<0]=s[x].f[1][y<0]=0,s[x].r1=s[x].r2=0;}inline void pushdown(int x){int l=s[x].ch[0],r=s[x].ch[1];if(s[x].tag){if(l)cover(l,s[x].tag);if(r)cover(r,s[x].tag);s[x].tag=0;}if(s[x].r1){if(l)rev1(l);if(r)rev1(r);s[x].r1=0;}if(s[x].r2){if(l)rev2(l);if(r)rev2(r);s[x].r2=0;}}inline void rotate(int x,int &k){int y=s[x].fa,z=s[y].fa,d=(x==s[y].ch[1]);if(y!=k)s[z].ch[y==s[z].ch[1]]=x;elsek=x;s[x].fa=z,s[y].fa=x,s[y].ch[d]=s[x].ch[d^1];if(s[x].ch[d^1])s[s[x].ch[d^1]].fa=y;s[x].ch[d^1]=y;pushup(y),pushup(x);}inline void splay(int x,int &k){while(x!=k){int y=s[x].fa,z=s[y].fa;if(y!=k){if((x==s[y].ch[0])^(y==s[z].ch[0]))rotate(x,k);elserotate(y,k);}rotate(x,k);}}int find(int x,int y){if(!x)return 0;pushdown(x);if(s[s[x].ch[0]].siz>=y)return find(s[x].ch[0],y);if(s[s[x].ch[0]].siz+1<y)return find(s[x].ch[1],y-s[s[x].ch[0]].siz-1);return x;}inline void split(int a,int b){splay(find(rt,a),rt),splay(find(rt,b+2),s[rt].ch[1]);}int build(int l,int r){if(l>r)return 0;int x=(l+r)>>1;s[x].ch[0]=build(l,x-1),s[x].ch[1]=build(x+1,r);if(s[x].ch[0])s[s[x].ch[0]].fa=x;if(s[x].ch[1])s[s[x].ch[1]].fa=x;pushup(x);return x;}inline int rd(){int ret=0,f=1;char gc=getchar();while(gc<‘0‘||gc>‘9‘){if(gc==‘-‘)f=-f;gc=getchar();}while(gc>=‘0‘&&gc<=‘9‘)ret=ret*10+(gc^‘0‘),gc=getchar();return ret*f;}int main(){//freopen("bz2329.in","r",stdin);n=rd(),m=rd();int i,a,b,x;scanf("%s",str+1);for(i=1;i<=n;i++)s[i+1].v=(str[i]==‘(‘)?-1:1;rt=build(1,n+2);for(i=1;i<=m;i++){scanf("%s",str),a=rd(),b=rd(),split(a,b),x=s[s[rt].ch[1]].ch[0];if(str[0]==‘R‘){scanf("%s",str);cover(x,(str[0]==‘(‘)?-1:1),pushup(s[x].fa),pushup(s[s[x].fa].fa);}if(str[0]==‘I‘)rev1(x),pushup(s[x].fa),pushup(s[s[x].fa].fa);if(str[0]==‘S‘)rev2(x),pushup(s[x].fa),pushup(s[s[x].fa].fa);if(str[0]==‘Q‘)printf("%d\n",((s[x].f[0][1]+1)>>1)+((s[x].f[1][0]+1)>>1));}return 0;}//4 5 (((( Replace 1 2 ) Query 1 2 Swap 2 3 Invert 3 4 Query 1 4//6 3 )(())( Q 1 6 Q 1 4 Q 3 4 

【BZOJ2329/2209】[HNOI2011]括号修复/[Jsoi2011]括号序列 Splay

原文地址:http://www.cnblogs.com/CQzhangyu/p/7954606.html

知识推荐

我的编程学习网——分享web前端后端开发技术知识。 垃圾信息处理邮箱 tousu563@163.com 网站地图
icp备案号 闽ICP备2023006418号-8 不良信息举报平台 互联网安全管理备案 Copyright 2023 www.wodecom.cn All Rights Reserved