【淼】关于 FHQ-Treap
查看原帖
【淼】关于 FHQ-Treap
232838
huangkx楼主2021/11/6 09:12

网上都说 FHQ-Treap 码量小,功能也强,蒟蒻就去学了学。
然后 愉 快 地写了 179179 行。。。

#include <bits/stdc++.h>
using namespace std;
int n;
int opt, x;
namespace FHQ_Treap_Space
{
	const int MAXN = 1e5 + 5;
	const int IMPOSSIBLE = 1e9;
	struct FHQ_Treap{
		int root, sum;
		int u, v, w, p;
		int result;
		struct Node{
			int value;
			int size;
			int priority;
			int left;
			int right;
		};
		Node tree[MAXN];
		void Initialize()
		{
			//初始化
			srand(time(0));
			root = sum = 0;
			tree[0].value = IMPOSSIBLE;
			tree[0].size = 0;
			tree[0].priority = 0;
			tree[0].left = 0;
			tree[0].right = 0;
			return;
		}
		int Make_Node(int value)
		{
			//新建节点,值为 value,返回新建的节点
			sum++;
			tree[sum].value = value;
			tree[sum].size = 1;
			tree[sum].priority = rand();
			tree[sum].left = 0;
			tree[sum].right = 0;
			return sum;
		}
		void Push_Up(int u)
		{
			//计算子树 u 的大小
			tree[u].size = tree[tree[u].left].size + tree[tree[u].right].size + 1;
			return;
		}
		void Split(int value, int w, int &u, int &v)
		{
			//分裂子树 w,值 <= value 的被分到子树 u,值 > value 的被分到子树 v
			if(w == 0){
				u = v = 0;
				return;
			}
			if(tree[w].value <= value){
				u = w;
				Split(value, tree[w].right, tree[w].right, v);
			}
			if(tree[w].value > value){
				v = w;
				Split(value, tree[w].left, u, tree[w].left);
			}
			Push_Up(w);
			return;
		}
		int Merge(int u, int v)
		{
			//合并子树 u,v,返回合并后的根节点
			if(u == 0 || v == 0) return u + v;
			if(tree[u].priority <= tree[v].priority){
				tree[u].right = Merge(tree[u].right, v);
				Push_Up(u);
				return u;
			}
			if(tree[u].priority > tree[v].priority){
				tree[v].left = Merge(u, tree[v].left);
				Push_Up(v);
				return v;
			}
		}
		void Insert(int value)
		{
			//插入值为 value 的节点
			Split(value, root, u, v);
			root = Merge(Merge(u, Make_Node(value)), v);
			return;
		}
		void Delete(int value)
		{
			//删除值为 value 的节点
			Split(value, root, u, w);
			Split(value-1, u, u, v);
			v = Merge(tree[v].left, tree[v].right);
			root = Merge(Merge(u, v), w);
			return;
		}
		int Size()
		{
			//查询节点个数
			return tree[root].size;
		}
		bool Search(int value)
		{
			//查询值为 value 的节点是否存在
			if(Size() == 0) return false;
			Split(value, root, u, w);
			Split(value-1, u, u, v);
			if(tree[v].value == value) result = 1;
			else result = 0;
			root = Merge(Merge(u, v), w);
			return result;
		}
		int Get_Rank(int value)
		{
			//查询值为 value 的节点的排名
			if(Search(value) == false) return IMPOSSIBLE;
			Split(value-1, root, u, v);
			result = tree[u].size + 1;
			root = Merge(u, v);
			return result;
		}
		int Get_Value(int rank)
		{
			//查询排名为 rank 的节点的值
			if(rank <= 0 || rank > Size()) return IMPOSSIBLE;
			p = root;
			while(true){
				if(tree[tree[p].left].size + 1 == rank) break;
				if(tree[tree[p].left].size + 1 <= rank){
					rank = rank - tree[tree[p].left].size - 1;
					p = tree[p].right;
				}
				if(tree[tree[p].left].size + 1 > rank) p = tree[p].left;
			}
			return tree[p].value;
		}
		int Get_Prefix(int value)
		{
			//查询值 < value 的节点中,值最大的节点的值
			if(Size() == 0) return IMPOSSIBLE;
			Split(value-1, root, u, v);
			p = u;
			while(tree[p].right != 0) p = tree[p].right;
			result = tree[p].value;
			root = Merge(u, v);
			return result;
		}
		int Get_Suffix(int value)
		{
			//查询值 > value 的节点中,值最小的节点的值
			if(Size() == 0) return IMPOSSIBLE;
			Split(value, root, u, v);
			p = v;
			while(tree[p].left != 0) p = tree[p].left;
			result = tree[p].value;
			root = Merge(u, v);
			return result;
		}
	};
}
FHQ_Treap_Space :: FHQ_Treap t;
int main()
{
	t.Initialize();
	scanf("%d", &n);
	while(n--){
		scanf("%d%d", &opt, &x);
		if(opt == 1) t.Insert(x);
		if(opt == 2) t.Delete(x);
		if(opt == 3) printf("%d\n", t.Get_Rank(x));
		if(opt == 4) printf("%d\n", t.Get_Value(x));
		if(opt == 5) printf("%d\n", t.Get_Prefix(x));
		if(opt == 6) printf("%d\n", t.Get_Suffix(x));
	}
	return 0;
}
//FHQ-Treap
2021/11/6 09:12
加载中...