【bzoj3224】Tyvj 1728 普通平衡树

题目描述:

您需要写一种数据结构(可参考题目标题),来维护一些数,其中需要提供以下操作:
1. 插入x数
2. 删除x数(若有多个相同的数,因只删除一个)
3. 查询x数的排名(若有多个相同的数,因输出最小的排名)
4. 查询排名为x的数
5. 求x的前驱(前驱定义为小于x,且最大的数)
6. 求x的后继(后继定义为大于x,且最小的数)

输入:

第一行为n,表示操作的个数,下面n行每行有两个数opt和x,opt表示操作的序号(1<=opt<=6)

输出:

对于操作3,4,5,6每行输出一个数,表示对应答案

样例输入:

10
1 106465
4 1
1 317721
1 460929
1 644985
1 84185
1 89851
6 81968
1 492737
5 493598

样例输出:
106465
84185
492737

题解:

平衡树模板题。

代码:

2016.04.13 Treap(unrotated)(这里找排名是一种非常慢的写法,原因是我写的另一种懒得调细节了(雾))。

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>

#ifdef WIN32
	#define LL "%I64d"
#else
	#define LL "%lld"
#endif

#ifdef CT
	#define debug(...) printf(__VA_ARGS__)
	#define setfile() 
#else
	#define debug(...)
	#define filename ""
	#define setfile() freopen(filename".in", "r", stdin); freopen(filename".out", "w", stdout);
#endif

#define R register
#define getc() (S == T && (T = (S = B) + fread(B, 1, 1 << 15, stdin), S == T) ? EOF : *S++)
#define dmax(_a, _b) ((_a) > (_b) ? (_a) : (_b))
#define dmin(_a, _b) ((_a) < (_b) ? (_a) : (_b))
#define cmax(_a, _b) (_a < (_b) ? _a = (_b) : 0)
#define cmin(_a, _b) (_a > (_b) ? _a = (_b) : 0)
char B[1 << 15], *S = B, *T = B;
inline int FastIn()
{
	R char ch; R int cnt = 0; R bool minus = 0;
	while (ch = getc(), (ch < '0' || ch > '9') && ch != '-') ;
	ch == '-' ? minus = 1 : cnt = ch - '0';
	while (ch = getc(), ch >= '0' && ch <= '9') cnt = cnt * 10 + ch - '0';
	return minus ? -cnt : cnt;
}
#define maxn 100010
const int Ta = 1 << 16 | 3, Tb = 33333331;
int Tc;
inline int randint() {return Tc = Ta * Tc + Tb;}
struct Treap
{
	int data, key, size;
	Treap *ls, *rs;
	Treap(int _val):data(_val), key(randint()), ls(NULL), rs(NULL), size(1){}
	inline void update()
	{
		size = (ls ? ls -> size : 0) + (rs ? rs -> size : 0) + 1;
	}
}*root;
inline int Size(Treap *x)
{
	return x ? x -> size : 0;
}
struct Pair
{
	Treap *fir, *sec;
};
Treap *Merge(Treap *a, Treap *b)
{
	if (!a) return b;
	if (!b) return a;
	if (a -> key < b -> key)
	{
		a -> rs = Merge(a -> rs, b);
		a -> update();
		return a;
	}
	else
	{
		b -> ls = Merge(a, b -> ls);
		b -> update();
		return b;
	}
}
Pair Split(Treap *x, int k)
{
	if (!x) return (Pair){NULL, NULL};
	Pair y; y.fir = NULL; y.sec = NULL;
	if (Size(x -> ls) >= k)
	{
		y = Split(x -> ls, k);
		x -> ls = y.sec;
		x -> update();
		y.sec = x;
	}
	else
	{
		y = Split(x -> rs, k - Size(x -> ls) - 1);
		x -> rs = y.fir;
		x -> update();
		y.fir = x;
	}
	return y;
}
inline int Find(R int k)
{
	Pair x = Split(root, k - 1);
	Pair y = Split(x.sec, 1);
	Treap *ans = y.fir;
	root = Merge(Merge(x.fir, ans), y.sec);
	return ans -> data;
}
inline int Get(Treap *x, R int val)
{
	if (!x) return 0;
	return val < x -> data ? Get(x -> ls, val) : Get(x -> rs, val) + Size(x -> ls) + 1;
}
inline void Insert(R int val)
{
	R int k = Get(root, val);
	Pair x = Split(root, k);
	Treap *pre = new Treap(val);
	root = Merge(Merge(x.fir, pre), x.sec);
}
inline void Delete(R int val)
{
	R int k = Get(root, val);
	Pair x = Split(root, k - 1);
	Pair y = Split(x.sec, 1);
	root = Merge(x.fir, y.sec);
}
inline int upper(R int val)
{
	R int ans = 1e9;
	Treap *tmp = root;
	while (tmp)
	{
		if (tmp -> data > val)
		{
			cmin(ans, tmp -> data);
			tmp = tmp -> ls;
		}
		else
			tmp = tmp -> rs;
	}
	return ans;
}
inline int lower(R int val)
{
	R int ans = -1e9;
	Treap *tmp = root;
	while (tmp)
	{
		if (tmp -> data < val)
		{
			cmax(ans, tmp -> data);
			tmp = tmp -> rs;
		}
		else tmp = tmp -> ls;
	}
	return ans;
}
void print(Treap *x)
{
	if (!x) return;
	print(x -> ls);
	printf("%d ",x -> data );
	print(x -> rs);
}
int main()
{
	root = NULL;
	for (R int Q = FastIn(); Q; --Q)
	{
		R int opt = FastIn(), x = FastIn();
		if (opt == 1) Insert(x);
		else if (opt == 2) Delete(x);
		else if (opt == 3)
		{
			R int ans = Get(root, x);
			while (ans > 1 && Find(ans - 1) == x) ans--;
			printf("%d\n", ans );
		}
		else if (opt == 4) printf("%d\n", Find(x) );
		else if (opt == 5) printf("%d\n",lower(x) );
		else printf("%d\n",upper(x) );
	}
	return 0;
}
/*
input:
10
1 106465
4 1
1 317721
1 460929
1 644985
1 84185
1 89851
6 81968
1 492737
5 493598

output:
106465
84185
492737

input2:
5
1 1
1 1
1 1
1 2
3 1
output2:
1
*/



 

posted @ 2016-04-13 18:31  cot  阅读(136)  评论(0编辑  收藏  举报