Splay模板bzoj3224

解析:http://www.cnblogs.com/zwfymqz/p/7898210.html

#include<bits/stdc++.h>
using namespace std;
inline int read()
{
    char c=getchar();int x=0,f=1;
    while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
    while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
    return x*f;
}
struct one
{
	int v,fa,ch[2],rec,sum;
};
one tree[500000];
int n,tot=0,pointnum=0;
#define root tree[0].ch[1]
int iden(int x)
{
	return tree[tree[x].fa].ch[0]==x?0:1;
}
inline void connect(int x,int fa,int how)
{
	tree[x].fa=fa;
	tree[fa].ch[how]=x;
}
inline void update(int x)
{
	tree[x].sum=tree[tree[x].ch[0]].sum+tree[tree[x].ch[1]].sum+tree[x].rec;}
inline void rotate(int x)
{
	int Y=tree[x].fa;
	int R=tree[Y].fa;
	int Yson=iden(x);
	int Rson=iden(Y);
	int B=tree[x].ch[Yson^1];
	connect(x,R,Rson);
	connect(Y,x,Yson^1);
	connect(B,Y,Yson);
	update(Y);update(x);
}
void splay(int x,int to)
{
	to=tree[to].fa;
	while(tree[x].fa!=to)
	{
		if(tree[tree[x].fa].fa==to)rotate(x);
		else if(iden(x)==iden(tree[x].fa))rotate(tree[x].fa),rotate(x);
		else rotate(x),rotate(x);
	}
}
void newpoint(int v,int fa)
{
	tree[++tot].v=v;
	tree[tot].fa=fa;
	tree[tot].sum=tree[tot].rec=1;
}
int build(int v)
{
	pointnum++;
	if(tot==0){root=1;newpoint(v,0);}
	else
	{
		int now=root;
		while(1)
		{
			tree[now].sum++;
			if(tree[now].v==v){tree[now].rec++;return now;}
			int nxt=v<tree[now].v?0:1;
			if(!tree[now].ch[nxt])
			{
				newpoint(v,now);tree[now].ch[nxt]=tot;return tot;
			}
			now=tree[now].ch[nxt];
		}
	}
	return 0;
}
inline void dele(int x)
{
	tree[x].v=tree[x].fa=tree[x].ch[0]=tree[x].rec=tree[x].sum=tree[x].ch[1]=0;
	if(x==tot)tot--;
}
int find(int v)
{
	int now=root;
	while(1)
	{
		if(tree[now].v==v){splay(now,root);return now;}
		int nxt=v<tree[now].v?0:1;
		if(!tree[now].ch[nxt])return 0;
		now=tree[now].ch[nxt];
	}
}
void pop(int v)
{
	int deal=find(v);
	if(!deal)return;
	pointnum--;
	if(tree[deal].rec>1){tree[deal].sum--;tree[deal].rec--;return;}
	if(!tree[deal].ch[0])root=tree[deal].ch[1],tree[root].fa=0;
	else
	{
		int le=tree[deal].ch[0];
		while(tree[le].ch[1])le=tree[le].ch[1];
		splay(le,tree[deal].ch[0]);
		int ri=tree[deal].ch[1];
		connect(ri,le,1);
		connect(le,0,1);
		update(le);
	}
	dele(deal);
}
void insert(int v)
{
	int p=build(v);splay(p,root);
}
int rank(int v)
{
	int ans=0,now=root;
	while(1)
	{
		if(tree[now].v==v){ans+=tree[tree[now].ch[0]].sum+1;splay(now,root);return ans;}
		if(now==0)return 0;
		if(v<tree[now].v)now=tree[now].ch[0];
		else ans+=tree[tree[now].ch[0]].sum+tree[now].rec,now=tree[now].ch[1];
	}
}
int arank(int x)
{
	int now=root;
	while(1)
	{
		int used=tree[now].sum-tree[tree[now].ch[1]].sum;
		if(x>tree[tree[now].ch[0]].sum&&x<=used)break;
		if(x<used)now=tree[now].ch[0];
		else x-=used,now=tree[now].ch[1];
	}
	splay(now,root);
	return tree[now].v;
}
int lower(int v)
{
	int now=root;
	int ans=-100000000;
	while(now)
	{
		if(tree[now].v<v&&tree[now].v>ans)ans=tree[now].v;
		if(v>tree[now].v)now=tree[now].ch[1];
		else now=tree[now].ch[0];
	}
	return ans;
}
int upper(int v)
{
	int now=root;
	int ans=100000000;
	while(now)
	{
		if(tree[now].v>v&&tree[now].v<ans)ans=tree[now].v;
		if(tree[now].v>v)now=tree[now].ch[0];
		else now=tree[now].ch[1];
	}
	return ans;
}
int main()
{
	//freopen("xf.in","r",stdin);
	scanf("%d",&n);
	int p1,p2;
	for(int i=1;i<=n;i++)
	{
		p1=read();p2=read();
		if(p1==1)insert(p2);
		else if(p1==2)pop(p2);
		else if(p1==3)printf("%d\n",rank(p2));
		else if(p1==4)printf("%d\n",arank(p2));
		else if(p1==5)printf("%d\n",lower(p2));
		else if(p1==6)printf("%d\n",upper(p2));
	}
	return 0;
}

  

posted @ 2018-02-07 18:30  mybing  阅读(175)  评论(0编辑  收藏  举报