记录编号 248706 评测结果 AAAAAAAAAA
题目名称 [Tyvj 1728]普通平衡树 最终得分 100
用户昵称 Gravatarmikumikumi 是否通过 通过
代码语言 C++ 运行时间 0.555 s
提交时间 2016-04-10 21:25:36 内存使用 2.34 MiB
显示代码纯文本
#include<cstdio>
#include<cmath>
#include<iostream>
using namespace std;
const int SIZEN=100010,INF=0x7fffffff/2;
const double alpha=0.75,lga=log(1.0/alpha);
int N;
int root,tot;
class miku
{
public:
	int fa;
	int ls,rs;
	int key;
	int siz;
	miku()
	{
		ls=rs=0; 
	}
	#define fa(x) tr[x].fa
	#define ls(x) tr[x].ls
	#define rs(x) tr[x].rs
	#define key(x) tr[x].key
	#define siz(x) tr[x].siz
}tr[SIZEN];
void prepare()//和某毒瘤数据结构一样,也要放哨兵
{
	root=1;tot=2;
	key(1)=-INF;rs(1)=2;siz(1)=2;
	key(2)=INF;fa(2)=1;siz(2)=1;
}
bool balance(int x)
{
	if(alpha*siz(x)<=max(siz(ls(x)),siz(rs(x)))) return 0;
	return 1;
}
int len=0;
int lis[SIZEN];
void dfs(int x)
{
	if(ls(x)) dfs(ls(x));
	lis[++len]=x;
	if(rs(x)) dfs(rs(x));
}
int built(int l,int r)
{
	if(l>r) return 0;
	int mid=(l+r)/2,x=lis[mid];
	ls(x)=built(l,mid-1),rs(x)=built(mid+1,r);
	fa(ls(x))=x;fa(rs(x))=x;
	siz(x)=siz(ls(x))+siz(rs(x))+1;
	return x;
}
void rebuilt(int x)
{
	len=0;
	dfs(x);
	int f=fa(x);
	int l;
	if(ls(f)==x) l=0;
	else l=1;
	int y=built(1,len);
	if(l==0) ls(f)=y,fa(y)=f;
	else rs(f)=y,fa(y)=f;
	if(root==x) root=y;
}
void insert(int t)
{
	int now=root,x=++tot,dep=0;
	siz(x)=1,key(x)=t;
	while(now)
	{
		siz(now)++;
		if(t<key(now))
		{
			if(ls(now)) now=ls(now);
			else
			{
				ls(now)=x;
				fa(x)=now;
				break;
			}
		}
		else
		{
			if(rs(now)) now=rs(now);
			else 
			{
				rs(now)=x;
				fa(x)=now;
				break;
			}
		}
		dep++;
	}
	if(dep>log(tot+1.0)/lga)
	{
		int r=0;
		for(now=x;now;now=fa(now)) if(!balance(now)) r=now;
		if(r) rebuilt(r);
	}
}
int find(int t)
{
	int now=root;
	while(now)
	{
		if(key(now)==t) return now;
		else if(key(now)<t) now=rs(now);
		else now=ls(now);
	}
	return now;
}
void erase(int x)
{
	if(ls(x)&&rs(x))
	{
		int y=ls(x);
		while(rs(y)) y=rs(y);
		key(x)=key(y);
		x=y;
	}
	int son;
	if(ls(x)) son=ls(x);else son=rs(x);
	if(ls(fa(x))==x) fa(ls(fa(x))=son)=fa(x);
	else fa(rs(fa(x))=son)=fa(x);
	for(int now=x;now;now=fa(now)) siz(now)--;
	if(x==root) root=son;
}
int rank(int t)
{
	int now=root,ans=0;
	while(now)
	{
		if(key(now)<t) ans+=siz(ls(now))+1,now=rs(now);
		else now=ls(now);
	}
	return ans;
}
int getth(int k)
{
	int now=root;
	while(now)
	{
		if(siz(ls(now))+1==k) return now;
		else if(siz(ls(now))>=k) now=ls(now);
		else k-=siz(ls(now))+1,now=rs(now);
	}
	return now;
}
int low(int t)
{
	int now=root,ans=-INF;
	while(now)
	{
		if(key(now)<t) ans=max(key(now),ans),now=rs(now);
		else now=ls(now);
	}
	return ans;
}
int high(int t)
{
	int now=root,ans=INF;
	while(now)
	{
		if(key(now)>t) ans=min(ans,key(now)),now=ls(now);
		else now=rs(now);
	}
	return ans;
}
int main()
{
	freopen("phs.in","r",stdin);
	freopen("phs.out","w",stdout);
	prepare();
	scanf("%d",&N);
	int cmd,x;
	for(int i=1;i<=N;i++)
	{
		scanf("%d%d",&cmd,&x);
		//cout<<"cmd:"<<cmd<<endl;
		if(cmd==1) insert(x);
		if(cmd==2) erase(find(x));
		if(cmd==3) printf("%d\n",rank(x));
		if(cmd==4) printf("%d\n",key(getth(x+1)));
		if(cmd==5) printf("%d\n",low(x));
		if(cmd==6) printf("%d\n",high(x));
	}
	return 0;
}