平衡树合集

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;
}
posted @ 2020-08-09 08:09  GK0328  阅读(125)  评论(0编辑  收藏  举报