标签:二叉搜索树 else swa 编号 tag highlight turn log pushd
以前看着非旋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);
}
标签:二叉搜索树 else swa 编号 tag highlight turn log pushd
原文地址:http://www.cnblogs.com/jefflyy/p/7498646.html