[BZOJ3223]文艺平衡树
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[BZOJ3223]文艺平衡树相关的知识,希望对你有一定的参考价值。
以前看着非旋treap的题解写了一发,没有真正理解
最近补了一下splay,于是用来练手
因为是区间翻转,子树大小不变,所以pushup时儿子对父亲没有影响
因此splay($x$)之前只需一路从根pushdown到$x$即可,不需要pushdown儿子
由于pushdown时交换儿子破坏了二叉搜索树的性质,故splay($x$)应该改为splay($k$),即splay排名第几的节点而不是splay节点编号
#include<stdio.h> int ch[100010][2],fa[100010],siz[100010],tag[100010],root,n; int build(int l,int r){ int mid=(l+r)>>1,ls=0,rs=0; if(l<mid)ls=build(l,mid-1); if(mid<r)rs=build(mid+1,r); siz[mid]=1; if(ls){ siz[mid]+=siz[ls]; ch[mid][0]=ls; fa[ls]=mid; } if(rs){ siz[mid]+=siz[rs]; ch[mid][1]=rs; fa[rs]=mid; } return mid; } void pushup(int x){ siz[x]=siz[ch[x][0]]+siz[ch[x][1]]+1; } void rot(int x){ int y,z,B,f; y=fa[x]; z=fa[y]; f=(ch[y][0]==x); if(root==y)root=x; B=ch[x][f]; if(B)fa[B]=y; fa[x]=z; fa[y]=x; ch[x][f]=y; ch[y][f^1]=B; if(ch[z][f^1]==y)ch[z][f^1]=x; if(ch[z][f]==y)ch[z][f]=x; pushup(y); pushup(x); } void swap(int&a,int&b){a^=b^=a^=b;} void pushdown(int x){ if(tag[x]){ swap(ch[x][0],ch[x][1]); if(ch[x][0])tag[ch[x][0]]^=1; if(ch[x][1])tag[ch[x][1]]^=1; tag[x]=0; } } void splay(int k){ int x,y,z; x=root; while(1){ pushdown(x); if(siz[ch[x][0]]>=k) x=ch[x][0]; else if(siz[ch[x][0]]+1<k){ k-=(siz[ch[x][0]]+1); x=ch[x][1]; }else break; } while(x!=root){ if(fa[x]==root) rot(x); else{ y=fa[x]; z=fa[y]; if((y==ch[z][0]&&x==ch[y][0])||(y==ch[z][1]&&x==ch[y][1])){ rot(y); rot(x); }else{ rot(x); rot(x); } } } } void reverse(int l,int r){ if(l==1){ if(r==n) tag[root]^=1; else{ splay(r+1); tag[ch[root][0]]^=1; splay(siz[ch[root][0]]-siz[ch[ch[root][0]][1]]); } return; } if(r==n){ splay(l-1); tag[ch[root][1]]^=1; splay(siz[ch[root][0]]+siz[ch[ch[root][1]][0]]+2); return; } splay(l-1); int t=root; root=ch[root][1]; splay(r-siz[ch[t][0]]); tag[ch[root][0]]^=1; root=fa[root]; splay(siz[ch[root][0]]+siz[ch[ch[ch[root][1]][0]][0]]+2); } void dfs(int x){ pushdown(x); if(ch[x][0])dfs(ch[x][0]); printf("%d ",x); if(ch[x][1])dfs(ch[x][1]); } int main(){ int m,l,r; scanf("%d%d",&n,&m); root=build(1,n); while(m--){ scanf("%d%d",&l,&r); reverse(l,r); } dfs(root); }
以上是关于[BZOJ3223]文艺平衡树的主要内容,如果未能解决你的问题,请参考以下文章