平衡树代码总结
Posted robin20050901
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了平衡树代码总结相关的知识,希望对你有一定的参考价值。
这里给出博主的几种平衡树模板代码
vector
代码:
// luogu-judger-enable-o2
#include<bits/stdc++.h>
#define rd(x) x=read()
using namespace std;
int n;
vector<int>v;
inline int read()
{
int f=1,x=0;char s=getchar();
while(s<‘0‘||s>‘9‘){if(s==‘-‘)f=-1;s=getchar();}
while(s>=‘0‘&&s<=‘9‘){x=x*10+s-‘0‘;s=getchar();}
return x*f;
}
int main()
{
rd(n);
for(int i=1;i<=n;i++)
{
int opt,x;
rd(opt),rd(x);
if(opt==1)v.insert(upper_bound(v.begin(),v.end(),x),x);
else if(opt==2)v.erase(lower_bound(v.begin(),v.end(),x));
else if(opt==3)printf("%d
",lower_bound(v.begin(),v.end(),x)-v.begin()+1);
else if(opt==4)printf("%d
",v[x-1]);
else if(opt==5)printf("%d
",*--lower_bound(v.begin(),v.end(),x));
else if(opt==6)printf("%d
",*upper_bound(v.begin(),v.end(),x));
}
return 0;
}
Treap:
// luogu-judger-enable-o2
#pragma GCC optimize(1)
#pragma GCC optimize(2)
#pragma GCC optimize(3)
#include<bits/stdc++.h>
#define rd(x) x=read()
#define N 100005
#define inf (1<<30)
using namespace std;
inline int read()
{
int f=1,x=0;char s=getchar();
while(s<‘0‘||s>‘9‘){if(s==‘-‘)f=-1;s=getchar();}
while(s>=‘0‘&&s<=‘9‘){x=x*10+s-‘0‘;s=getchar();}
return x*f;
}
int q;
int ncnt,root;
struct T{
int s,v,cnt,rnd,ch[2];
}t[N];
void pushup(int rt){t[rt].s=t[t[rt].ch[0]].s+t[t[rt].ch[1]].s+t[rt].cnt;}
void rotate(int &rt,int d)
{
int k=t[rt].ch[d^1];
t[rt].ch[d^1]=t[k].ch[d];
t[k].ch[d]=rt;
pushup(rt),pushup(k);
rt=k;
}
void ins(int &rt,int x)
{
if(!rt)
{
rt=++ncnt,t[rt].s=t[rt].cnt=1,t[rt].v=x,t[rt].rnd=rand();
return ;
}
if(t[rt].v==x){t[rt].cnt++,t[rt].s++;return ;}
int d=(x>t[rt].v);
ins(t[rt].ch[d],x);
if(t[rt].rnd<t[t[rt].ch[d]].rnd)rotate(rt,d^1);
pushup(rt);
}
void del(int &rt,int x)
{
if(!rt)return;
if(x<t[rt].v)del(t[rt].ch[0],x);
else if(x>t[rt].v)del(t[rt].ch[1],x);
else
if(t[rt].ch[0])
if(t[rt].ch[1])
{
int d=(t[t[rt].ch[0]].rnd>t[t[rt].ch[1]].rnd);
rotate(rt,d);
del(t[rt].ch[d],x);
}
else
{
rotate(rt,1);
del(t[rt].ch[1],x);
}
else
if(t[rt].ch[1])
{
rotate(rt,0);
del(t[rt].ch[0],x);
}
else
{
t[rt].cnt--,t[rt].s--;
if(!t[rt].cnt)rt=0;
}
pushup(rt);
}
int rank(int rt,int x)
{
if(!rt)return 0;
if(t[rt].v==x)return t[t[rt].ch[0]].s+1;
else if(t[rt].v<x)return t[t[rt].ch[0]].s+t[rt].cnt+rank(t[rt].ch[1],x);
else return rank(t[rt].ch[0],x);
}
int find(int rt,int x)
{
if(!rt)return 0;
if(t[t[rt].ch[0]].s>=x)return find(t[rt].ch[0],x);
else if(t[t[rt].ch[0]].s+t[rt].cnt<x)return find(t[rt].ch[1],x-t[rt].cnt-t[t[rt].ch[0]].s);
else return t[rt].v;
}
int pre(int rt,int x)
{
if(!rt)return -inf;
if(t[rt].v>=x)return pre(t[rt].ch[0],x);
else return max(t[rt].v,pre(t[rt].ch[1],x));
}
int suc(int rt,int x)
{
if(!rt)return inf;
if(t[rt].v<=x)return suc(t[rt].ch[1],x);
else return min(t[rt].v,suc(t[rt].ch[0],x));
}
int main()
{
rd(q);
while(q--)
{
int opt,x;
rd(opt),rd(x);
if(opt==1)ins(root,x);
else if(opt==2)del(root,x);
else if(opt==3)printf("%d
",rank(root,x));
else if(opt==4)printf("%d
",find(root,x));
else if(opt==5)printf("%d
",pre(root,x));
else printf("%d
",suc(root,x));
}
return 0;
}
Splay
// luogu-judger-enable-o2
#pragma GCC optimize(1)
#pragma GCC optimize(2)
#pragma GCC optimize(3)
#include<iostream>
#include<cstdio>
#define rd(x) x=read()
#define N 100005
using namespace std;
int q;
int ncnt,root;
struct T{
int s,v,cnt,fa,ch[2];
}t[N];
inline int read()
{
int f=1,x=0;char s=getchar();
while(s<‘0‘||s>‘9‘){if(s==‘-‘)f=-1;s=getchar();}
while(s>=‘0‘&&s<=‘9‘){x=x*10+s-‘0‘;s=getchar();}
return x*f;
}
int chk(int rt){return t[t[rt].fa].ch[1]==rt;}
int pushup(int rt){return t[rt].s=t[t[rt].ch[0]].s+t[t[rt].ch[1]].s+t[rt].cnt;}
void rotate(int x)
{
int y=t[x].fa,z=t[y].fa,k=chk(x),w=t[x].ch[k^1];
t[y].ch[k]=w,t[w].fa=y;
t[z].ch[chk(y)]=x,t[x].fa=z;
t[x].ch[k^1]=y,t[y].fa=x;
pushup(y),pushup(x);
}
void splay(int x,int goal=0)
{
while(t[x].fa!=goal)
{
int y=t[x].fa,z=t[y].fa;
if(z!=goal)
{
if(chk(x)==chk(y))rotate(y);
else rotate(x);
}
rotate(x);
}
if(!goal)root=x;
}
void ins(int x)
{
int rt=root,pos=0;
while(rt&&t[rt].v!=x)pos=rt,rt=t[rt].ch[x>t[rt].v];
if(rt)t[rt].cnt++;
else
{
rt=++ncnt;
if(pos)t[pos].ch[x>t[pos].v]=rt;
t[rt].ch[0]=t[rt].ch[1]=0;
t[rt].fa=pos,t[rt].v=x;
t[rt].cnt=t[rt].s=1;
}
splay(rt);
}
void find(int x)
{
int rt=root;
while(t[rt].ch[x>t[rt].v]&&t[rt].v!=x)rt=t[rt].ch[x>t[rt].v];
splay(rt);
}
int rank(int k)
{
int rt=root;
while("zth loves msy")
{
if(t[rt].ch[0]&&k<=t[t[rt].ch[0]].s)rt=t[rt].ch[0];
else if(k>t[t[rt].ch[0]].s+t[rt].cnt)k-=t[t[rt].ch[0]].s+t[rt].cnt,rt=t[rt].ch[1];
else return rt;
}
}
int pre(int x)
{
find(x);
if(t[root].v<x)return root;
int rt=t[root].ch[0];
while(t[rt].ch[1])rt=t[rt].ch[1];
return rt;
}
int suc(int x)
{
find(x);
if(t[root].v>x)return root;
int rt=t[root].ch[1];
while(t[rt].ch[0])rt=t[rt].ch[0];
return rt;
}
void del(int x)
{
int last=pre(x),next=suc(x);
splay(last),splay(next,last);
int _del=t[next].ch[0];
if(t[_del].cnt>1)
{
t[_del].cnt--;
splay(_del);
}
else t[next].ch[0]=0;
}
int main()
{
rd(q);
ins(0x3f3f3f3f),ins(0xcfcfcfcf);
while(q--)
{
int opt,x;
rd(opt),rd(x);
if(opt==1)ins(x);
else if(opt==2)del(x);
else if(opt==3){find(x);printf("%d
",t[t[root].ch[0]].s);}
else if(opt==4)printf("%d
",t[rank(x+1)].v);
else if(opt==5)printf("%d
",t[pre(x)].v);
else printf("%d
",t[suc(x)].v);
}
return 0;
}
替罪羊树
// luogu-judger-enable-o2
#pragma GCC optimize(1)
#pragma GCC optimize(2)
#pragma GCC optimize(3)
#include<bits/stdc++.h>
#define rd(x) x=read()
#define N 100005
using namespace std;
struct T{
int s,f,v,d,ch[2];
}t[N];
int ncnt,root,cnt;
int Lrd[N],r[N];
int n;
const double p=0.75;
inline int read()
{
int f=1,x=0;char s=getchar();
while(s<‘0‘||s>‘9‘){if(s==‘-‘)f=-1;s=getchar();}
while(s>=‘0‘&&s<=‘9‘){x=x*10+s-‘0‘;s=getchar();}
return x*f;
}
void init(int rt)
{
t[rt].s=t[rt].f=1;
t[rt].ch[0]=t[rt].ch[1]=0;
}
bool bal(int rt){return (double)t[rt].f*p>(double)max(t[t[rt].ch[0]].f,t[t[rt].ch[1]].f);}
void lrd(int rt)
{
if(!rt)return;
lrd(t[rt].ch[0]);
if(t[rt].d)Lrd[++cnt]=rt;
lrd(t[rt].ch[1]);
}
void pushup(int rt)
{
t[rt].s=t[t[rt].ch[0]].s+t[t[rt].ch[1]].s+1;
t[rt].f=t[t[rt].ch[0]].f+t[t[rt].ch[1]].f+1;
}
void setup(int &rt,int l,int r)
{
int mid=(l+r)>>1;
rt=Lrd[mid];
if(l==r){init(rt);return;}
if(l<mid)setup(t[rt].ch[0],l,mid-1);
else t[rt].ch[0]=0;
setup(t[rt].ch[1],mid+1,r);
pushup(rt);
}
void rebuild(int &rt)
{
cnt=0;
lrd(rt);
if(cnt)setup(rt,1,cnt);
else rt=0;
}
void check(int rt,int v)
{
int k=(v>t[rt].v);
while(t[rt].ch[k])
{
if(!bal(t[rt].ch[k]))
{
rebuild(t[rt].ch[k]);
return ;
}
rt=t[rt].ch[k];
k=(v>t[rt].v);
}
}
void ins(int &rt,int x)
{
if(!rt)
{
rt=++ncnt,t[rt].v=x,t[rt].d=1,init(rt);
return ;
}
t[rt].s++,t[rt].f++;
if(x<=t[rt].v)ins(t[rt].ch[0],x);
else ins(t[rt].ch[1],x);
}
int rank(int x)
{
int rk=1,rt=root;
while(rt)
{
if(t[rt].v>=x)rt=t[rt].ch[0];
else rk+=t[t[rt].ch[0]].f+t[rt].d,rt=t[rt].ch[1];
}
return rk;
}
int find(int x)
{
int rt=root;
while(rt)
{
if(t[rt].d&&t[t[rt].ch[0]].f+1==x)return t[rt].v;
else if(t[t[rt].ch[0]].f>=x)rt=t[rt].ch[0];
else x-=t[rt].d+t[t[rt].ch[0]].f,rt=t[rt].ch[1];
}
}
void del(int &rt,int rk)
{
if(t[rt].d&&t[t[rt].ch[0]].f+1==rk)
{
t[rt].d=0;
t[rt].f--;
return ;
}
t[rt].f--;
if(t[t[rt].ch[0]].f+t[rt].d>=rk)del(t[rt].ch[0],rk);
else del(t[rt].ch[1],rk-t[rt].d-t[t[rt].ch[0]].f);
}
void Del(int x)
{
del(root,rank(x));
if((double)t[root].s*p>(double)t[root].f)rebuild(root);
}
int main()
{
rd(n);
while(n--)
{
int opt,x;
rd(opt),rd(x);
if(opt==1)ins(root,x),check(root,x);
else if(opt==2)Del(x);
else if(opt==3)printf("%d
",rank(x));
else if(opt==4)printf("%d
",find(x));
else if(opt==5)printf("%d
",find(rank(x)-1));
else printf("%d
",find(rank(x+1)));
}
return 0;
}
FHQ treap
// luogu-judger-enable-o2
#pragma GCC optimize(1)
#pragma GCC optimize(2)
#pragma GCC optimize(3)
#include<bits/stdc++.h>
#define rd(x) x=read()
#define N 100005
using namespace std;
int n;
int ncnt;
struct T{
int v,rnd,s,ch[2];
}t[N];
inline int read()
{
int f=1,x=0;char s=getchar();
while(s<‘0‘||s>‘9‘){if(s==‘-‘)f=-1;s=getchar();}
while(s>=‘0‘&&s<=‘9‘){x=x*10+s-‘0‘;s=getchar();}
return x*f;
}
void update(int rt){t[rt].s=t[t[rt].ch[0]].s+t[t[rt].ch[1]].s+1;}
int NewNode(int v)
{
t[++ncnt].s=1;
t[ncnt].v=v;
t[ncnt].rnd=rand();
return ncnt;
}
int merge(int x,int y)
{
if(!x||!y) return x+y;
if(t[x].rnd<t[y].rnd)
{
t[x].ch[1]=merge(t[x].ch[1],y);
update(x);
return x;
}
else
{
t[y].ch[0]=merge(x,t[y].ch[0]);
update(y);
return y;
}
}
void split(int rt,int pos,int &l,int &r)
{
if(!rt)l=r=0;
else
{
if(t[rt].v<=pos)
{
l=rt;
split(t[rt].ch[1],pos,t[rt].ch[1],r);
}
else
{
r=rt;
split(t[rt].ch[0],pos,l,t[rt].ch[0]);
}
update(rt);
}
}
int kth(int rt,int pos)
{
while(1)
{
if(pos<=t[t[rt].ch[0]].s)rt=t[rt].ch[0];
else if(pos==t[t[rt].ch[0]].s+1) return rt;
else
{
pos-=t[t[rt].ch[0]].s+1;
rt=t[rt].ch[1];
}
}
}
int main()
{
srand(time(0));
rd(n);
int root=0,x,y,z;
while(n--)
{
int opt,a;
rd(opt),rd(a);
if(opt==1)
{
split(root,a,x,y);
root=merge(merge(x,NewNode(a)),y);
}
else if(opt==2)
{
split(root,a,x,z);
split(x,a-1,x,y);
y=merge(t[y].ch[0],t[y].ch[1]);
root=merge(merge(x,y),z);
}
else if(opt==3)
{
split(root,a-1,x,y);
printf("%d
",t[x].s+1);
root=merge(x,y);
}
else if(opt==4)printf("%d
",t[kth(root,a)].v);
else if(opt==5)
{
split(root,a-1,x,y);
printf("%d
",t[kth(x,t[x].s)].v);
root=merge(x,y);
}
else if(opt==6)
{
split(root,a,x,y);
printf("%d
",t[kth(y,1)].v);
root=merge(x,y);
}
}
return 0;
}
以上是关于平衡树代码总结的主要内容,如果未能解决你的问题,请参考以下文章