Slay学习笔记

洛咕日报
普通平衡树
题解

#include<bits/stdc++.h>
using namespace std;
int son[1000010][2],val[1000010],cnt[1000010],Fa[1000010],size[1000010];
int root,ncnt;
int n,pd,num;
int Check(int x)
{
	return son[Fa[x]][1]==x;
}
int pushup(int x)
{
    size[x]=size[son[x][0]]+size[son[x][1]]+cnt[x];
}
int rotate(int x)
{
	int y=Fa[x],z=Fa[y],chk=Check(x),tmp=son[x][!chk];
	son[y][chk]=tmp;
	Fa[tmp]=y;
	son[z][Check(y)]=x;
	Fa[x]=z;
	son[x][!chk]=y;
	Fa[y]=x;
	pushup(x);
	pushup(y);
}
int Splay(int x,int goal=0)
{
	for(;Fa[x]!=goal;)
	{
		int y=Fa[x],z=Fa[y];
		if(z!=goal)
		{
			if(Check(x)==Check(y))
			{
				rotate(y);
			}
			else
			{
				rotate(x);
			}
		}
		rotate(x);
	}
	if(!goal)
	{
		root=x;
	}
}
int Find(int x)
{
	if(!root)
	{
		return 0;
	}
	int Res=root;
	for(;son[Res][x>val[Res]]&&x!=val[Res];)
	{
		Res=son[Res][x>val[Res]];
	}
	Splay(Res);
}
int insert(int x)
{
	int Res=root,p=0;
	for(;Res&&val[Res]!=x;)
	{
        p=Res;
        Res=son[Res][x>val[Res]];
    }
    if(Res)
    {
    	cnt[Res]++;
    }
    else
    {
    	Res=++ncnt;
        if(p)
        {
        	son[p][x>val[p]]=Res;
        }
        son[Res][0]=0;
		son[Res][1]=0;
        val[Res]=x;
		Fa[Res]=p;
        cnt[Res]=1;
		size[Res]=1;
    }
    Splay(Res);
}
int xth(int x)
{
	int Res=root;
	for(;;)
	{
		if(x<=size[son[Res][0]]&&son[Res][0])
		{
			Res=son[Res][0];
		}
		else
		{
			if(x>size[son[Res][0]]+cnt[Res])
			{
				x-=size[son[Res][0]]+cnt[Res];
				Res=son[Res][1];
			}
			else
			{
				return Res;
			}
		}
	}
}
int RANK(int x)
{
	Find(x);
	return size[son[root][0]];
}
int Pre(int x)
{
	Find(x);
	if(val[root]<x)
	{
		return root;
	}
	int Res=son[root][0]; 
	for(;son[Res][1];)
	{
		Res=son[Res][1];
	}
	return Res;
}
int Suc(int x)
{
	Find(x);
	if(val[root]>x)
	{
		return root;
	}
	int Res=son[root][1]; 
	for(;son[Res][0];)
	{
		Res=son[Res][0];
	}
	return Res;
}
int Delete(int x)
{
	int las=Pre(x),nex=Suc(x);
	Splay(las);
	Splay(nex,las);
	int DEL=son[nex][0];
	if(cnt[DEL]>1)
	{
        cnt[DEL]--;
        Splay(DEL);
    }
    else
	{
		son[nex][0]=0;
	} 
}
int main()
{
	cin>>n;
	insert(-1000000000);
	insert(1000000000);
	for(int i=1;i<=n;i++)
	{
		cin>>pd>>num;
		if(pd==1)
		{
			 insert(num); 
		}
		if(pd==2)
		{
			 Delete(num);
		}
		if(pd==3)
		{
			 cout<<RANK(num)<<endl;
		}
		if(pd==4)
		{
			 cout<<val[xth(num+1)]<<endl;
		}
		if(pd==5)
		{
			 cout<<val[Pre(num)]<<endl;
		}
		if(pd==6)
		{
			 cout<<val[Suc(num)]<<endl;
		}
	}
}

文艺平衡树
题解

#include<bits/stdc++.h>
using namespace std;
int son[1000010][2],val[1000010],cnt[1000010],Fa[1000010],size[1000010],rev[1000010];
int root,ncnt;
int n,m,pd,num;
int Check(int x)
{
    return son[Fa[x]][1]==x;
}
void pushup(int x)
{
    size[x]=size[son[x][0]]+size[son[x][1]]+cnt[x];
}
void pushdown(int x)
{
    if(rev[x])
    {
        swap(son[x][0],son[x][1]);
        rev[son[x][0]]=!rev[son[x][0]];
        rev[son[x][1]]=!rev[son[x][1]];
        rev[x]=0;
    }
}
void rotate(int x)
{
    int y=Fa[x],z=Fa[y],chk=Check(x),tmp=son[x][!chk];
    son[y][chk]=tmp;
    Fa[tmp]=y;
    son[z][Check(y)]=x;
    Fa[x]=z;
    son[x][!chk]=y;
    Fa[y]=x;
    pushup(y);
    pushup(x);
}
void Splay(int x,int goal=0)
{
    for(;Fa[x]!=goal;)
    {
        int y=Fa[x],z=Fa[y];
        if(z!=goal)
        {
            if(Check(x)==Check(y))
            {
                rotate(x);
            }
            else
            {
                rotate(y);
            }
        }
        rotate(x);
    }
    if(!goal)
    {
        root=x;
    }
}
void Find(int x)
{
    if(!root)
    {
        return ;
    }
    int Res=root;
    for(;son[Res][x>val[Res]]&&x!=val[Res];)
    {
        Res=son[Res][x>val[Res]];
    }
    Splay(Res);
}
void insert(int x)
{
    int Res=root,p=0;
    for(;Res&&val[Res]!=x;)
    {
        p=Res;
        Res=son[Res][x>val[Res]];
    }
    if(Res)
    {
    	cnt[Res]++;
    }
    else
    {
    	Res=++ncnt;
        if(p)
        {
        	son[p][x>val[p]]=Res;
        }
        son[Res][0]=0;
        son[Res][1]=0;
        val[Res]=x;
        Fa[Res]=p;
        cnt[Res]=1;
        size[Res]=1;
    }
    Splay(Res);
}
int xth(int x)
{
    int Res=root;
    for(;;)
    {
        pushdown(Res); 
        if(x<=size[son[Res][0]]&&son[Res][0])
        {
            Res=son[Res][0];
        }
        else
        {
            if(x>size[son[Res][0]]+cnt[Res])
            {
                x-=size[son[Res][0]]+cnt[Res];
                Res=son[Res][1];
            }
            else
            {
                return Res;
            }
        }
    }
}
void REV(int L,int R)
{
    int x=xth(L),y=xth(R+2);
    Splay(x);
    Splay(y,x);
    rev[son[y][0]]=!rev[son[y][0]];
}
int RANK(int x)
{
    Find(x);
    return size[son[root][0]];
}
int Pre(int x)
{
    Find(x);
    if(val[root]<x)
    {
        return root;
    }
    int Res=son[root][0]; 
    for(;son[Res][1];)
    {
        Res=son[Res][1];
    }
    return Res;
}
int Suc(int x)
{
    Find(x);
    if(val[root]>x)
    {
        return root;
    }
    int Res=son[root][1]; 
    for(;son[Res][0];)
    {
        Res=son[Res][0];
    }
    return Res;
}
void Delete(int x)
{
    int las=Pre(x),nex=Suc(x);
    Splay(las);
    Splay(nex,las);
    int DEL=son[nex][0];
    if(cnt[DEL]>1)
    {
        cnt[DEL]--;
        Splay(DEL);
    }
    else
    {
        son[nex][0]=0;
    } 
}
void output(int x)
{
    pushdown(x);
    if (son[x][0])
        output(son[x][0]);
    if(val[x]&&val[x]<=n) 
        printf("%d ", val[x]);
    if(son[x][1])
        output(son[x][1]);
}
int main()
{
    cin>>n>>m;
    for(int i=0;i<=n+1;i++)
    {
        insert(i);
    }
    int ipl,ipr; 
    for(int i=1;i<=m;i++)
    {
        cin>>ipl>>ipr;
        REV(ipl,ipr);
    }
    output(root);
}

简单点的平衡树(要long long)

#include<bits/stdc++.h>
using namespace std;
long long n,q,pd,num;
long long val[1000010],fa[1000010],size[1000010],cnt[1000010],son[1000010][2];
long long root,ncnt;
int Check(long long x)
{
	return son[fa[x]][1]==x;
}
void pushup(long long x)
{
	size[x]=size[son[x][1]]+size[son[x][0]]+cnt[x];
}
void rotate(long long x)
{
	long long y=fa[x],z=fa[y],chk=Check(x),tt=son[x][!chk];
	son[y][chk]=tt;
	fa[tt]=y;
	son[z][Check(y)]=x;
	fa[x]=z;
	son[x][!chk]=y;
	fa[y]=x;
	pushup(y);
	pushup(x);
}
void Splay(long long x,long long goal=0)
{
	while(fa[x]!=goal)
	{
		long long y=fa[x],z=fa[y];
		if(z!=goal)
		{
			if(Check(x)==Check(y))
			{
				rotate(y);
			}
			else
			{
				rotate(x);
			}
		}
		rotate(x);
	}
	if(!goal)
	{
		root=x;
	}
}
void Find(long long x)
{
	if(!root)
		return;
	long long res=root;
	for(;son[res][x>val[res]]&&x!=val[res];)
	{
		res=son[res][x>val[res]];
	}
	Splay(res);
}
void insert(long long x)
{
	long long res=root,p=0;
	for(;res&&x!=val[res];)
	{
		p=res;
		res=son[res][x>val[res]];
	}
	if(res)
	{
		cnt[res]++;
	}
	else
	{
		res=++ncnt;
		if(p)
		{
			son[p][x>val[p]]=res;
		}
		son[res][1]=0;
		son[res][0]=0;
		cnt[res]=1;
		val[res]=x;
		fa[res]=p;
		size[res]=1;
	}
	Splay(res);
}
int xth(long long x)
{
	long long res=root;
	for(;;)
	{
		if(x<=size[son[res][1]]&&son[res][1])
		{
			res=son[res][1];
		}
		else
		{
			if(x>size[son[res][1]]+cnt[res])
			{
				x-=size[son[res][1]]+cnt[res];
				res=son[res][0];
			}
			else
			{
				return res;
			} 
		}
	}
}
int main()
{
	cin>>n>>q;
    insert(-10000000000000);
    insert(10000000000000);
    long long iptmp;
    for(int i=1;i<=n;i++)
    {
        cin>>iptmp;
        insert(iptmp);
    }
    for(int i=1;i<=q;i++)
    {
        cin>>pd>>num;
        if(pd==1)
        {
             cout<<val[xth(num+1)]<<endl;
        }
        if(pd==2)
        {
             insert(num); 
        }
    }
} 
posted @ 2019-03-15 18:59  G_A_TS  阅读(501)  评论(0编辑  收藏  举报