比赛 清华集训2017模板练习 评测结果 AAAAAAAAAA
题目名称 普通平衡树 最终得分 100
用户昵称 栋霸霸 运行时间 0.291 s
代码语言 C++ 内存使用 4.13 MiB
提交时间 2017-07-17 15:08:06
显示代码纯文本
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cmath>
#include<algorithm>
#include<queue>
#include<vector>
using namespace std;
const int maxn=200000;
int key[maxn],lc[maxn],rc[maxn],fa[maxn],siz[maxn];
int tot,root;
int T;
void update(int x)
{
	siz[x]=siz[lc[x]]+1+siz[rc[x]];
}
void r_rotate(int x)
{
	int y=fa[x];
	lc[y]=rc[x];
	if(rc[x]!=0) fa[rc[x]]=y;
	fa[x]=fa[y];
	if(y==lc[fa[y]]) lc[fa[y]]=x;
	else rc[fa[y]]=x;
	fa[y]=x;
	rc[x]=y;
	update(x);
	update(y);
}
void l_rotate(int x)
{
	int y=fa[x];
	rc[y]=lc[x];
	if(lc[x]!=0) fa[lc[x]]=y;
	fa[x]=fa[y];
	if(y==lc[fa[y]]) lc[fa[y]]=x;
	else rc[fa[y]]=x;
	fa[y]=x;
	lc[x]=y;
	update(x);
	update(y);
}
void splay(int x,int s)
{
	int p;
	while(fa[x]!=s)
	{
		p=fa[x];
		if(fa[p]==s)
		{
			if(x==lc[p]) r_rotate(x);
			else l_rotate(x);
			break;
		}
		if(x==lc[p])
		{
			if(p==lc[fa[p]]) r_rotate(p),r_rotate(x);
			else r_rotate(x),l_rotate(x);
		}
		else
		{
			if(p==rc[fa[p]]) l_rotate(p),l_rotate(x);
			else l_rotate(x),r_rotate(x);
		}
	}
	if(s==0) root=x;
	update(x);
}
int find(int v)
{
	int x=root;
	while(x!=0)
	{
		if(v<key[x]) x=lc[x];
		else if(v>key[x]) x=rc[x];
		else if(v==key[x])
		{
			splay(x,0);
			return x;
		}
	}
	return -1;
}
void New_node(int &x,int fath,int v)
{
	x=++tot;
	lc[x]=rc[x]=0;
	siz[x]=1;
	fa[x]=fath;
	key[x]=v;
}
void insert(int v)
{
	if(root==0)
	{
		New_node(rc[0],0,v);
		root=tot;
		return ;
	}
	int p,x=root;
	while(x!=0)
	{
		p=x;
		if(v<=key[x]) siz[x]++,x=lc[x];
		else siz[x]++,x=rc[x];
	}
	if(v<=key[p]) New_node(lc[p],p,v);
	else New_node(rc[p],p,v);
	splay(tot,0);
}
int getmax(int x)
{
	if(rc[x]!=0) return getmax(rc[x]);
	return x;
}
int getmin(int x)
{
	if(lc[x]!=0) return getmin(lc[x]);
	return x;
}
int getpre(int x)
{
	splay(x,0);
	return getmax(lc[x]);
}
int getne(int x)
{
	splay(x,0);
	return getmin(rc[x]);
}
void Delete(int v)
{
	int x=find(v);
	int pp=getmax(lc[x]);
	int nn=getmin(rc[x]);
	if(lc[x]==0||rc[x]==0)
	{
		if(lc[x]==0&&rc[x]==0)
		{
			root=0;
			rc[0]=0;
			return ;
		}
		if(lc[x]==0)
		{
			rc[0]=rc[x];
			fa[rc[x]]=0;
			root=rc[x];
			rc[x]=0;
			siz[x]=1;
			return ;
		}
		else
		{
			rc[0]=lc[x];
			fa[lc[x]]=0;
			root=lc[x];
			lc[x]=0;
			siz[x]=1;
			return ;
		}
	}
	splay(pp,0);
	splay(nn,root);
	fa[lc[nn]]=0;
	siz[lc[nn]]=1;
	lc[nn]=0;
	update(nn);
	update(pp);
}
int rank(int rt,int v)
{
	if(rt==0) return 1;
	if(v<=key[rt]) return rank(lc[rt],v);
	else return siz[lc[rt]]+1+rank(rc[rt],v);
}
int findkth(int x,int k)
{
	if(siz[lc[x]]+1==k) return key[x];
	if(siz[lc[x]]+1>k) return findkth(lc[x],k);
	return findkth(rc[x],k-siz[lc[x]]-1);
}

int pred(int rt,int v)
{
	if(rt==0)  return v;
	if(v<=key[rt]) return pred(lc[rt],v);
	else
	{
		int ans=pred(rc[rt],v);
		if(ans==v) return key[rt];
		return ans;
	}
}
int succ(int rt,int v)
{
	if(rt==0) return v;
	if(v>=key[rt]) return succ(rc[rt],v);
	else
	{
		int ans=succ(lc[rt],v);
		if(ans==v) return key[rt];
		return ans;
	}
}
int main()
{
	freopen("phs.in","r",stdin);
	freopen("phs.out","w",stdout);
	scanf("%d",&T);
	while (T--)
	{
		int kin,num;
		scanf("%d%d",&kin,&num);
		if(kin==1)
			insert(num);
		else if(kin==2)
			Delete(num);
		else if(kin==3)
			printf("%d\n",rank(root,num));
		else if (kin==4)
			printf("%d\n",findkth(root,num));
		else if (kin==5)
			printf("%d\n",pred(root,num));
		else if (kin==6)
			printf("%d\n",succ(root,num));
	}
	return 0;
}