BZOJ-3224 普通平衡树

一道BST的练习题。

Treap版:

#include <cstdlib>
#include <cstdio>
#include <algorithm>
#include <iostream>
#include <cctype>
#include <cstring>
#define rep(i, l, r) for(int i=l; i<=r; i++)
#define clr(x, c) memset(x, c, sizeof(x))
#define update(x) s[x]=s[l[x]]+s[r[x]]+1
#define maxn 100009
#define inf 0x7fffffff
using namespace std;
inline int read()
{
	int x=0, f=1; char ch=getchar();
	while (!isdigit(ch)) {if (ch=='-') f=-1; ch=getchar();}
	while (isdigit(ch)) {x=x*10+ch-'0'; ch=getchar();}
	return x*f;
}
int n=read();


int l[maxn], r[maxn], s[maxn], k[maxn], pr[maxn], roof, V;
inline void Init(){srand(233); roof=V=0;}
inline void Left(int &v)
{
	int u=r[v];
	r[v]=l[u], l[u]=v;
	update(v), update(u);
	v=u;
}
inline void Right(int &v)
{
	int u=l[v];
	l[v]=r[u], r[u]=v;
	update(v), update(u);
	v=u;
}
void Insert(int x, int &v)
{
	if (!v)
	{
		v=++V; l[v]=r[v]=0, s[v]=1, k[v]=x, pr[v]=rand(); return;
	}
	if (x < k[v])
	{
		Insert(x, l[v]); update(v);
		if (pr[l[v]] > pr[v]) Right(v);
	}
	else 
	{
		Insert(x, r[v]); update(v);
		if (pr[r[v]] > pr[v]) Left(v);
	}
}
void Delete(int x, int &v)
{
	if (x==k[v])
	{
		if (!l[v]) {v=r[v]; return;}
		else if (!r[v]) {v=l[v]; return;}
		else if (pr[l[v]] > pr[r[v]]) {Right(v); Delete(x, r[v]);}
		else {Left(v); Delete(x, l[v]);}
	} else Delete(x, x<k[v] ? l[v] : r[v]);
	update(v);
}
int Rank(int x, int v)
{
	if (!v) return 0;
	if (x>k[v]) return s[l[v]]+1+Rank(x, r[v]);
	else return Rank(x, l[v]);
}
int Select(int n, int v)
{
	if (s[l[v]]==n) return k[v];
	if (n>s[l[v]]) return Select(n-s[l[v]]-1, r[v]);
	else return Select(n, l[v]);
}
int Suf(int x)
{
	int rec=inf;
	for(int v=roof; v; v=x<k[v] ? l[v] : r[v]) 
		if (k[v]>x) rec=min(rec, k[v]);
	return rec;
}
int Pre(int x)
{
	int rec=-inf;
	for(int v=roof; v; v=x<=k[v] ? l[v] : r[v]) 
		if (k[v]<x) rec=max(rec, k[v]);
	return rec;
}

int main()
{
	Init(); 
	rep(i, 1, n)
	{
		int a=read();
		if (a==1) Insert(read(), roof);
		else if (a==2) Delete(read(), roof);
		else if (a==3) printf("%d\n", Rank(read(), roof)+1);
		else if (a==4) printf("%d\n", Select(read()-1, roof));
		else if (a==5) printf("%d\n", Pre(read())); else printf("%d\n", Suf(read()));
	}
	return 0;
}

  

posted @ 2015-04-21 20:16  NanoApe  阅读(141)  评论(0编辑  收藏  举报
AmazingCounters.com