平衡树(包括FHQ与Splay)
无旋treap(FHQ)
基本操作
新建
int New(int val)
{
tot++;
v[tot].val=val;
v[tot].rnd=rand();
v[tot].size=1;
return tot;
}
分裂
void split(int rt,int val,int &x,int &y)
{
if(!rt)
{
x=y=0;
return;
}
if(v[rt].val<=val)
{
x=rt;
split(rson,val,rson,y);
}
else
{
y=rt;
split(lson,val,x,lson);
}
pushup(rt);
}
合并
int merge(int x,int y)
{
if(!x||!y) return x+y;
if(v[x].rnd<v[y].rnd)
{
v[x].rs=merge(v[x].rs,y);
pushup(x);
return x;
}
else
{
v[y].ls=merge(x,v[y].ls);
pushup(y);
return y;
}
}
插入
void insert(int x)
{
int y,z;
split(root,x,y,z);
root=merge(merge(y,New(x)),z);
}
删除
void del(int x)
{
int y,z,q;
split(root,x,y,z);
split(y,x-1,y,q);
q=merge(v[q].ls,v[q].rs);
root=merge(merge(y,q),z);
}
第K大
int Kth(int rt,int k)
{
while(1)
{
if(k<=v[lson].size) rt=lson;
else if(k==v[lson].size+1) return v[rt].val;
else
{
k-=(v[lson].size+1);
rt=rson;
}
}
}
前驱/后继
int pre(int x)
{
int y,z;
split(root,x-1,y,z);
int ret=Kth(y,v[y].size);
root=merge(y,z);
return ret;
}
int bck(int x)
{
int y,z;
split(root,x,y,z);
int ret=Kth(z,1);
root=merge(y,z);
return ret;
}
区间操作(以翻转为例)
void pushup(int rt)
{
v[rt].size=v[lson].size+v[rson].size+1;
}
void pushdown(int rt)
{
if(!rt||!v[rt].lazy) return;
swap(lson,rson);
v[lson].lazy^=1;
v[rson].lazy^=1;
v[rt].lazy=0;
}
void split(int rt,int k,int &x,int &y)
{
if(!rt)
{
x=y=0;
return;
}
pushdown(rt);
if(k>v[lson].size)
{
x=rt;
k-=v[lson].size+1;
split(rson,k,rson,y);
}
else
{
y=rt;
split(lson,k,x,lson);
}
pushup(rt);
}
int merge(int x,int y)
{
if(!x||!y) return x+y;
if(v[x].rnd<v[y].rnd)
{
pushdown(x);
v[x].rs=merge(v[x].rs,y);
pushup(x);
return x;
}
else
{
pushdown(y);
v[y].ls=merge(x,v[y].ls);
pushup(y);
return y;
}
}
void reverse(int l,int r)
{
int x,y,z;
split(root,r,x,y);
split(x,l-1,x,z);
v[z].lazy^=1;
root=merge(merge(x,z),y);
}
void output(int rt)
{
if(!rt) return;
pushdown(rt);
output(lson);
cout<<v[rt].val<<" ";
output(rson);
}
splay
关键点
辅助操作
bool dir(int x)
{
return x==v[v[x].fa].ch[1];
}
void pushup(int rt)
{
v[rt].siz=v[rt].cnt+v[v[rt].ch[0]].siz+v[v[rt].ch[1]].siz;
}
旋转伸展
void rotate(int x)
{
int y=v[x].fa;
int z=v[y].fa;
bool r=dir(x);
v[y].ch[r]=v[x].ch[!r];
v[x].ch[!r]=y;
if(z) v[z].ch[dir(y)]=x;
if(v[y].ch[r]) v[v[y].ch[r]].fa=y;
v[y].fa=x;
v[x].fa=z;
pushup(y);
pushup(x);
}
void splay(int &z,int x)
{
int w=v[z].fa,y=v[x].fa;
while(y!=w)
{
if(v[y].fa!=w) rotate(dir(x)==dir(y)?y:x);
rotate(x);
y=v[x].fa;
}
z=x;
}
其它
void find(int &z,int val)
{
if(!z) return;
int x=z,y=z;
while(x&&v[x].val!=val)
{
y=x;
x=v[x].ch[val>v[x].val];
}
splay(z,x?x:y);
}
void loc(int &z,int k)
{
int x=z;
while(1)
{
if(v[v[x].ch[0]].siz>=k) x=v[x].ch[0];
else if(v[v[x].ch[0]].siz+v[x].cnt>=k) break;
else
{
k-=v[v[x].ch[0]].siz+v[x].cnt;
x=v[x].ch[1];
}
}
splay(z,x);
}
int Kth(int k)
{
if(k>v[root].siz) return -1;
loc(root,k);
return v[root].val;
}
int merge(int x,int y)
{
if(!x||!y) return x+y;
loc(y,1);
v[y].ch[0]=x;
v[x].fa=y;
pushup(y);
return y;
}
void insert(int val)
{
int x=root,y=0;
while(x&&v[x].val!=val)
{
y=x;
x=v[x].ch[val>v[x].val];
}
if(x) ++v[x].cnt,++v[x].siz;
else
{
x=++tot;
v[x].val=val;
v[x].cnt=1;
v[x].siz=1;
v[x].fa=y;
if(y) v[y].ch[val>v[y].val]=x;
}
splay(root,x);
}
bool del(int val)
{
find(root,val);
if(!root||v[root].val!=val) return false;
v[root].cnt--,v[root].siz--;
if(!v[root].cnt)
{
int x=v[root].ch[0],y=v[root].ch[1];
v[x].fa=v[y].fa=0;
root=merge(x,y);
}
return true;
}
int findsize(int val)
{
find(root,val);
return v[v[root].ch[0]].siz+(v[root].val<val ?v[root].cnt:0)+1;
}
int pre(int val)
{
find(root,val);
if(root&&v[root].val<val) return v[root].val;
int x=v[root].ch[0];
if(!x) return -1;
while(v[x].ch[1]) x=v[x].ch[1];
splay(root,x);
return v[x].val;
}
int bck(int val)
{
find(root,val);
if(root&&v[root].val>val) return v[root].val;
int x=v[root].ch[1];
if(!x) return -1;
while(v[x].ch[0]) x=v[x].ch[0];
splay(root,x);
return v[x].val;
}
FHQ可持久化
在分裂合并时加上克隆操作即可
int colne(int rt)
{
v[++tot]=v[rt];
return tot;
}

浙公网安备 33010602011771号