[BZOJ3223]文藝平衡樹
阿新 • • 發佈:2017-09-09
light include logs tag pla treap 父親 printf 破壞
以前看著非旋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]文藝平衡樹