平衡树合集
https://www.luogu.com.cn/problem/P3369
\(fhq\_treap\)
#include<bits/stdc++.h>
#define N 100005
using namespace std;
struct node
{
int v,sz,ls,rs,rk;
}s[N];
int cnt,n,m,x,y,z,g,opt,root;
inline int read()
{
int w=1,s=0;
char ch=getchar();
while (ch<'0'||ch>'9')
{
if (ch=='-')
w=-1;
ch=getchar();
}
while ('0'<=ch&&ch<='9')
{
s=s*10+ch-'0';
ch=getchar();
}
return s*w;
}
inline int newnode(int x)
{
cnt++;
s[cnt].v=x;
s[cnt].sz=1;
s[cnt].ls=0;
s[cnt].rs=0;
s[cnt].rk=rand();
return cnt;
}
inline void update(int x)
{
s[x].sz=s[s[x].ls].sz+s[s[x].rs].sz+1;
}
void split(int &x,int &y,int now,int k)
{
if (!now)
{
x=y=0;
return;
}
if (s[now].v<=k)
{
x=now;
split(s[now].rs,y,s[now].rs,k);
} else
{
y=now;
split(x,s[now].ls,s[now].ls,k);
}
update(now);
}
int merge(int x,int y)
{
if (!x||!y)
return x|y;
if (s[x].rk<s[y].rk)
{
s[x].rs=merge(s[x].rs,y);
update(x);
return x;
} else
{
s[y].ls=merge(x,s[y].ls);
update(y);
return y;
}
}
inline int kth(int now,int k)
{
for (;;)
{
if (s[s[now].ls].sz>=k)
now=s[now].ls; else
if (s[s[now].ls].sz+1==k)
return now; else
{
k-=s[s[now].ls].sz+1;
now=s[now].rs;
}
}
}
int main()
{
srand(time(NULL));
scanf("%d",&m);
while (m --> 0)
{
opt=read();
g=read();
if (opt==1)
{
split(x,y,root,g);
root=merge(merge(x,newnode(g)),y);
}
if (opt==2)
{
split(x,y,root,g);
split(x,z,x,g-1);
z=merge(s[z].ls,s[z].rs);
root=merge(merge(x,z),y);
}
if (opt==3)
{
split(x,y,root,g-1);
printf("%d\n",s[x].sz+1);
root=merge(x,y);
}
if (opt==4)
printf("%d\n",s[kth(root,g)].v);
if (opt==5)
{
split(x,y,root,g-1);
printf("%d\n",s[kth(x,s[x].sz)].v);
root=merge(x,y);
}
if (opt==6)
{
split(x,y,root,g);
printf("%d\n",s[kth(y,1)].v);
root=merge(x,y);
}
}
return 0;
}
\(Splay\)
#include<iostream>
#include<cstdio>
#include<algorithm>
#define ls(x) a[x].ch[0]
#define rs(x) a[x].ch[1]
#define root rs(0)
#define fa(x) a[x].f
#define id(x) (ls(fa(x))==x?0:1)
#define N 100005
#define INF 1000000007
using namespace std;
int n,opt,x,cnt;
struct node
{
int sz,val,f,rec,ch[2];
}a[N];
int newnode(int x)
{
cnt++;
a[cnt].sz=a[cnt].rec=1;
a[cnt].val=x,a[cnt].f=0;
ls(cnt)=rs(cnt)=0;
return cnt;
}
void update(int x)
{
a[x].sz=a[ls(x)].sz+a[rs(x)].sz+a[x].rec;
}
void connect(int x,int F,int son)
{
a[F].ch[son]=x;
a[x].f=F;
}
void rot(int x)
{
int y=fa(x);
int r=fa(y);
int yson=id(x),rson=id(y);
connect(a[x].ch[yson^1],y,yson);
connect(y,x,yson^1);
connect(x,r,rson);
update(y),update(x);
}
void splay(int x,int rt)
{
rt=fa(rt);
while (fa(x)!=rt)
{
int y=fa(x);
if (fa(y)==rt)
rot(x); else
if (id(x)==id(y))
rot(y),rot(x); else
rot(x),rot(x);
}
}
void Insert(int x)
{
if (!root)
{
root=newnode(x);
return;
}
int g=root;
while (1)
{
a[g].sz++;
if (a[g].val==x)
{
a[g].rec++;
splay(g,root);
return;
}
int nxt=(x<a[g].val)?0:1;
if (!a[g].ch[nxt])
{
connect(newnode(x),g,nxt);
splay(a[g].ch[nxt],root);
return;
}
g=a[g].ch[nxt];
}
}
int find(int x)
{
int g=root;
while (1)
{
if (!g)
return -1;
if (a[g].val==x)
{
splay(g,root);
return g;
}
int nxt=(x<a[g].val)?0:1;
g=a[g].ch[nxt];
}
}
void Delete(int x)
{
int pos=find(x);
if (pos==-1)
return;
if (a[pos].rec>1)
{
a[pos].rec--;
a[pos].sz--;
splay(pos,root);
return;
}
if (!ls(pos) && !rs(pos))
root=0; else
if (!ls(pos))
root=rs(pos),fa(root)=0; else
{
int g=ls(root);
while (rs(g))
g=rs(g);
splay(g,ls(pos));
connect(rs(pos),ls(pos),1);
connect(ls(pos),0,1);
}
}
int rk(int x)
{
int q=find(x);
if (q==-1)
return -1;
return a[ls(q)].sz+1;
}
int kth(int x)
{
int g=root;
while (1)
{
if (!g)
return -1;
if (a[ls(g)].sz>=x)
g=ls(g); else
if (a[ls(g)].sz<x && a[ls(g)].sz+a[g].rec>=x)
{
splay(g,root);
return a[g].val;
} else
x-=a[ls(g)].sz+a[g].rec,g=rs(g);
}
}
int pre(int x)
{
int ans=-INF;
int g=root;
while (1)
{
if (a[g].val<x)
{
ans=a[g].val;
if (!rs(g))
{
splay(g,root);
return ans;
}
g=rs(g);
} else
{
if (!ls(g))
{
splay(g,root);
return ans;
}
g=ls(g);
}
}
}
int suf(int x)
{
int ans=INF;
int g=root;
while (1)
{
if (a[g].val>x)
{
ans=a[g].val;
if (!ls(g))
{
splay(g,root);
return ans;
}
g=ls(g);
} else
{
if (!rs(g))
{
splay(g,root);
return ans;
}
g=rs(g);
}
}
}
int main()
{
scanf("%d",&n);
for (int i=1;i<=n;i++)
{
scanf("%d%d",&opt,&x);
if (opt==1)
Insert(x); else
if (opt==2)
Delete(x); else
if (opt==3)
printf("%d\n",rk(x)); else
if (opt==4)
printf("%d\n",kth(x)); else
if (opt==5)
printf("%d\n",pre(x)); else
if (opt==6)
printf("%d\n",suf(x));
}
return 0;
}
\(Scapegoat \quad Tree\)
#include<iostream>
#include<cstdio>
#include<algorithm>
#define INF 1000000007
#define N 100005
#define ls(x) a[x].ch[0]
#define rs(x) a[x].ch[1]
#define v(x) a[x].val
#define s(x) a[x].siz
#define c(x) a[x].cnt
#define D double
using namespace std;
D alpha=0.8;
int n,root,tot,p,opt,x,m[N],cur[N],q1=0,q2=0;
struct Scapegoat
{
int ch[2],val,siz,cnt;
}a[N];
int newnode(int x)
{
int g=m[tot--];
ls(g)=rs(g)=0;
c(g)=s(g)=1;
v(g)=x;
return g;
}
bool bad(int x)
{
return ((D)s(x)*alpha<=(D)max(s(ls(x)),s(rs(x))));
}
void update(int x)
{
s(x)=s(ls(x))+s(rs(x))+c(x);
}
void dfs(int now)
{
if (!now)
return;
dfs(ls(now));
cur[++p]=now;
dfs(rs(now));
}
void build(int l,int r,int &now)
{
int mid=(l+r) >> 1;
now=cur[mid];
if (l==r)
{
ls(now)=rs(now)=0;
s(now)=c(now);
return;
}
if (l<mid)
build(l,mid-1,ls(now)); else
ls(now)=0;
build(mid+1,r,rs(now));
update(now);
}
void rebuild(int &x)
{
p=0;
dfs(x);
build(1,p,x);
}
void ins(int &now,int x)
{
if (!now)
{
now=newnode(x);
return;
}
s(now)++;
if (v(now)==x)
{
c(now)++;
return;
}
int nxt=(x<v(now))?0:1;
ins(a[now].ch[nxt],x);
if (bad(now))
q2=-1; else
if (q2==-1)
q1=now,q2=nxt;
}
int rmin(int &rt)
{
if (ls(rt))
{
int ret=rmin(ls(rt));
update(rt);
if (bad(rt))
q2=-1; else
if (q2==-1)
q1=rt,q2=0;
return ret;
}
int ret=rt;
rt=rs(rt);
return ret;
}
void del(int &now,int x)
{
if (!now)
return;
s(now)--;
if (v(now)==x)
{
c(now)--;
if (!c(now))
{
if (!ls(now))
m[++tot]=now,now=rs(now); else
if (!rs(now))
m[++tot]=now,now=ls(now); else
{
int g=rmin(rs(now));
if (q2==-1)
q1=now,q2=1;
v(now)=v(g);
c(now)=c(g);
m[++tot]=g;
update(now);
if (bad(now))
q2=-1;
}
}
return;
}
int nxt=(x<v(now))?0:1;
del(a[now].ch[nxt],x);
if (bad(now))
q2=-1; else
if (q2==-1)
q1=now,q2=nxt;
}
int rk(int x)
{
int ans=1;
int g=root;
while (g)
{
if (x<=v(g))
g=ls(g); else
{
ans+=s(ls(g))+c(g);
g=rs(g);
}
}
return ans;
}
int kth(int k)
{
int g=root;
while (g)
{
if (s(ls(g))>=k)
g=ls(g); else
if (s(ls(g))+c(g)>=k)
return v(g); else
k-=s(ls(g))+c(g),g=rs(g);
}
return -1;
}
int pre(int x)
{
int g=root;
int ans=-INF;
while (g)
{
if (x<=v(g))
g=ls(g); else
{
ans=max(ans,v(g));
g=rs(g);
}
}
return ans;
}
int suf(int x)
{
int g=root;
int ans=INF;
while (g)
{
if (x>=v(g))
g=rs(g); else
{
ans=min(ans,v(g));
g=ls(g);
}
}
return ans;
}
int main()
{
for (int i=100000;i;i--)
m[++tot]=i;
scanf("%d",&n);
while (n --> 0)
{
scanf("%d%d",&opt,&x);
if (opt==1)
{
q1=q2=0;
ins(root,x);
if (q2==-1)
rebuild(root); else
if (q1)
rebuild(a[q1].ch[q2]);
}
if (opt==2)
{
q1=q2=0;
del(root,x);
if (q2==-1)
rebuild(root); else
if (q1)
rebuild(a[q1].ch[q2]);
}
if (opt==3)
printf("%d\n",rk(x)); else
if (opt==4)
printf("%d\n",kth(x)); else
if (opt==5)
printf("%d\n",pre(x)); else
if (opt==6)
printf("%d\n",suf(x));
}
return 0;
}
\(pre\)和\(suf\)函数可以被代替:
if (opt==5)
printf("%d\n",kth(rk(x)-1)); else
if (opt==6)
printf("%d\n",kth(rk(x+1)));
\(Treap\)
#include<cstdio>
#include<iostream>
#include<algorithm>
#define N 100005
#define ls(x) a[x].ch[0]
#define rs(x) a[x].ch[1]
#define s(x) a[x].sz
#define cnt(x) a[x].Vcnt
#define v(x) a[x].val
#define key(x) a[x].rd
#define sn(x,y) a[x].ch[y]
#define INF 1000000007
using namespace std;
int opt,x,n,tot,root;
struct Treap
{
int ch[2],sz,val,rd,Vcnt;
}a[N];
int newnode(int x)
{
tot++;
ls(tot)=rs(tot)=0;
cnt(tot)=s(tot)=1;
v(tot)=x;
key(tot)=rand();
return tot;
}
void update(int x)
{
s(x)=s(ls(x))+s(rs(x))+cnt(x);
}
void rot(int &x,int c)
{
int son=sn(x,c);
sn(x,c)=sn(son,c^1);
sn(son,c^1)=x;
update(x),update(son);
x=son;
}
void ins(int &x,int z)
{
if (!x)
{
x=newnode(z);
return;
}
s(x)++;
if (v(x)==z)
{
cnt(x)++;
return;
}
int nxt=(z<v(x))?0:1;
ins(sn(x,nxt),z);
if (key(sn(x,nxt))<key(x))
rot(x,nxt);
}
void del(int &x,int z)
{
if (!x)
return;
if (v(x)==z)
{
if (cnt(x)>1)
{
cnt(x)--;
s(x)--;
return;
}
if (!ls(x) || !rs(x))
{
x=ls(x)|rs(x);
return;
}
int nxt=key(ls(x))>key(rs(x));
rot(x,nxt);
del(x,z);
} else
{
s(x)--;
int nxt=(z<v(x))?0:1;
del(sn(x,nxt),z);
}
}
int rk(int x)
{
int g=root;
int ans=1;
while (g)
{
if (v(g)==x)
return ans+s(ls(g)); else
if (v(g)<x)
ans=ans+s(ls(g))+cnt(g),g=rs(g); else
g=ls(g);
}
return ans;
}
int kth(int k)
{
int g=root;
while (g)
{
if (s(ls(g))>=k)
g=ls(g); else
if (s(ls(g))+cnt(g)>=k)
return v(g); else
k-=s(ls(g))+cnt(g),g=rs(g);
}
}
int pre(int x)
{
int g=root;
int ans=-INF;
while (g)
{
if (v(g)>=x)
g=ls(g); else
{
ans=max(ans,v(g));
g=rs(g);
}
}
return ans;
}
int suf(int x)
{
int g=root;
int ans=INF;
while (g)
{
if (v(g)<=x)
g=rs(g); else
{
ans=min(ans,v(g));
g=ls(g);
}
}
return ans;
}
int main()
{
srand(time(NULL));
scanf("%d",&n);
for (int i=1;i<=n;i++)
{
scanf("%d%d",&opt,&x);
if (opt==1)
ins(root,x); else
if (opt==2)
del(root,x); else
if (opt==3)
printf("%d\n",rk(x));
if (opt==4)
printf("%d\n",kth(x)); else
if (opt==5)
printf("%d\n",pre(x)); else
if (opt==6)
printf("%d\n",suf(x));
}
return 0;
}