分享web开发知识

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

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

[BZOJ2209][JSOI2011]括号序列(splay)

发布时间:2023-09-06 01:55责任编辑:沈小雨关键词:暂无标签

有一个结论:对于一个括号序列,把它化简成)))(((这个形式之后,设)的数量为x,(的数量为y,则答案为$\lceil \frac{x}{2} \rceil + \lceil \frac{y}{2} \rceil$。

考虑x和y怎么求,把(看成1,)看成-1,要求的就是最小前缀和与最大后缀和。

记录lmn,lmx,rmn,rmx,反转时相互交换,翻转时打标记,各种操作splay维护即可。

 1 #include<cstdio> 2 #include<algorithm> 3 #define rep(i,l,r) for (int i=l; i<=r; i++) 4 using namespace std; 5 ?6 const int N=100010; 7 int n,m,op,rt,l,r,f[N],sz[N],v[N],sm[N],ch[N][2],lmn[N],rmn[N],lmx[N],rmx[N],rev[N],ops[N]; 8 char c; 9 10 void Rev(int x){ rev[x]^=1; swap(ch[x][0],ch[x][1]); swap(lmn[x],rmn[x]); swap(lmx[x],rmx[x]); }11 void Ops(int x){12 ????ops[x]^=1; sm[x]=-sm[x]; v[x]=-v[x];13 ????swap(lmn[x],lmx[x]); swap(rmn[x],rmx[x]);14 ????lmn[x]=-lmn[x]; rmn[x]=-rmn[x]; lmx[x]=-lmx[x]; rmx[x]=-rmx[x];15 }16 17 void push(int x){18 ????int l=ch[x][0],r=ch[x][1];19 ????if (rev[x]) Rev(l),Rev(r),rev[x]=0;20 ????if (ops[x]) Ops(l),Ops(r),ops[x]=0;21 }22 23 void upd(int x){24 ????int l=ch[x][0],r=ch[x][1];25 ????sz[x]=sz[l]+sz[r]+1; sm[x]=sm[l]+sm[r]+v[x];26 ????lmn[x]=min(lmn[l],sm[l]+v[x]+lmn[r]);27 ????lmx[x]=max(lmx[l],sm[l]+v[x]+lmx[r]);28 ????rmn[x]=min(rmn[r],sm[r]+v[x]+rmn[l]);29 ????rmx[x]=max(rmx[r],sm[r]+v[x]+rmx[l]);30 }31 32 void rot(int &rt,int x){33 ????int y=f[x],z=f[y],w=ch[y][1]==x;34 ????if (y==rt) rt=x; else ch[z][ch[z][1]==y]=x;35 ????f[x]=z; f[y]=x; f[ch[x][w^1]]=y;36 ????ch[y][w]=ch[x][w^1]; ch[x][w^1]=y; upd(y);37 }38 39 void splay(int &rt,int x){40 ????while (x!=rt){41 ????????int y=f[x],z=f[y];42 ????????if (y!=rt) rot(rt,((ch[z][1]==y)^(ch[y][1]==x)) ? x : y);43 ????????rot(rt,x);44 ????}45 ????upd(x);46 }47 48 int find(int x,int k){49 ????push(x); int l=ch[x][0],r=ch[x][1];50 ????if (k==sz[l]+1) return x;51 ????if (k<=sz[l]) return find(l,k); else return find(r,k-sz[l]-1);52 }53 54 int build(int L,int R){55 ????if (L>R) return 0;56 ????if (L==R){57 ????????sm[L]=v[L]; sz[L]=1;58 ????????if (v[L]==-1) lmn[L]=rmn[L]=-1;59 ????????if (v[L]==1) lmx[L]=rmx[L]=1;60 ????????return L;61 ????}62 ????int mid=(L+R)>>1;63 ????f[ch[mid][0]=build(L,mid-1)]=mid;64 ????f[ch[mid][1]=build(mid+1,R)]=mid;65 ????upd(mid); return mid;66 }67 68 int split(int l,int r){69 ????int x=find(rt,l),y=find(rt,r+2);70 ????splay(rt,x); splay(ch[x][1],y); return ch[y][0];71 }72 73 int main(){74 ????freopen("bzoj2209.in","r",stdin);75 ????freopen("bzoj2209.out","w",stdout);76 ????scanf("%d%d",&n,&m);77 ????rep(i,2,n+1) scanf(" %c",&c),v[i]=(c==‘(‘) ? 1 : -1;78 ????rt=build(1,n+2);79 ????rep(i,1,m){80 ????????scanf("%d%d%d",&op,&l,&r); int x=split(l,r);81 ????????if (op==0) printf("%d\n",(rmx[x]+1)/2-(lmn[x]-1)/2);82 ????????????else if (op==1) Ops(x); else Rev(x);83 ????}84 ????return 0;85 }

[BZOJ2209][JSOI2011]括号序列(splay)

原文地址:https://www.cnblogs.com/HocRiser/p/9063046.html

知识推荐

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