平衡树 splay区间翻转 模板

#include
#include
#include
using namespace std;
#define keytree ch[ch[root][1]][0]  
#define L(x) ch[x][0]  
#define R(x) ch[x][1]
#define N 100010
int ch[N][2],pre[N],cnt[N],size[N],val[N],small[N],rev[N],key[N];
int tot,root;
int a[N],n;
void newnode(int &u,int fa,int w,int KEY)
{
	u=++tot;
	ch[u][0]=ch[u][1]=rev[u]=0;
	pre[u]=fa;cnt[u]=size[u]=1;
	val[u]=small[u]=w;
	key[u]=KEY;
}
void up(int u)
{
	size[u]=cnt[u]+size[L(u)]+size[R(u)];
	small[u]=min(val[u],min(small[L(u)],small[R(u)]));
}
void down(int u)
{
	if(rev[u])
	{
		if(L(u))rev[L(u)]^=1;
		if(R(u))rev[R(u)]^=1;
		swap(L(u),R(u));
		rev[u]=0;
	}
}
void rotate(int u,int kind)//kind表示u在fa的哪一边
{
	int fa=pre[u];
	down(fa);down(u);
	ch[fa][kind]=ch[u][!kind];
	pre[ch[u][!kind]]=fa;
	if(pre[fa])ch[pre[fa]][ch[pre[fa]][1]==fa]=u;
	pre[u]=pre[fa];
	ch[u][!kind]=fa;
	pre[fa]=u;
	up(fa);up(u);
}
void splay(int u,int goal)
{
	int fa,kind;
	down(u);
	while(pre[u]!=goal)
	{
		if(pre[pre[u]]==goal)
		{
			down(pre[u]);down(u);
			rotate(u,R(pre[u])==u);
		}
		else 
		{
			fa=pre[u];
			down(pre[u]);down(fa);down(u);
			kind=R(pre[fa])==fa;
			if(ch[fa][kind]!=u)//不在同一侧 
			{
				rotate(u,!kind);
				rotate(u,kind);
			}
			else 
			{
				rotate(fa,kind);
				rotate(u,kind);
			}
		}
	}
	up(u);
	if(goal==0)root=u;
}
int getkth(int u,int k)//第k个键值的点的编号 
{
    down(u);
    int s=size[L(u)]+cnt[u];
    if(s==k) return u;
    if(s>k) return getkth(L(u),k);
    else return getkth(R(u),k-s);
}  
int find(int u,int x)//查找键值为x的点的编号 
{                    // 有反转标记时不可用
	down(u);
	if(key[u]==x)return u;
	if(key[u]>x)
	{
		if(!L(u))return -1;
		return find(L(u),x);
	}
	if(key[u]1)
	{
		cnt[x]--;
		return ;
	}
	splay(x,0);
	if(L(root))
	{
		int p=getpre(x);
		splay(p,root);
		R(p)=R(root);
		pre[R(root)]=p;
		root=p;
		pre[p]=0;
		up(root);
	}
	else
	{
		root=R(root);
        pre[root]=0;
	}
}
void build(int &u,int l,int r,int fa)//按pos为键值
{                        //val为数的大小 a存数的大小
    if(l>r)return ;
    int mid=(l+r)>>1;
    newnode(u,fa,a[mid],mid);
    build(L(u),l,mid-1,u);
    build(R(u),mid+1,r,u);
    up(u);
}
void init()  
{
    root=tot=0;
    L(root)=R(root)=pre[root]=size[root]=rev[root]=0;
    val[root]=small[root]=N;  
    newnode(root,0,N,0);
    newnode(R(root),root,N,N);  
    build(keytree,1,n,R(root));
    up(R(root));  
    up(root);  
}
int getmin(int u,int x)//得到最小值的相对位置 
{
    down(u);
    if(val[u]==x) return 1+size[L(u)];
    if(small[L(u)]==x) return getmin(L(u),x);
    if(small[R(u)]==x) return size[L(u)]+cnt[u]+getmin(R(u),x);
}
//--------------------------------------------------基本操作 

你可能感兴趣的:(splay)