FHQ treap

非常难忘 昨晚学的 调到凌晨4点多

#include<bits/stdc++.h>
using namespace std;
using ll = long long;
namespace IO {
template<class I>
inline void read(I &x) {
	x = 0;
	I f = 1;
	char c = getchar();
	while (c < '0' || c > '9') {
		if (c == '-') f = -1;
		c = getchar();
	}
	while (c >= '0' && c <= '9') {
		x = x * 10 + c - '0';
		c = getchar();
	}
	x *= f;
}
template <typename T, typename ...Args>
inline void read(T &tmp, Args &...tmps) {
	read(tmp);
	read(tmps...);
}
template<class T>
inline void write(T x) {
	if (x < 0) {
		putchar('-');
		x = -x;
	}
	if (x >= 10) {
		write(x / 10);
	}
	putchar(x % 10 + '0');
}
void mc()
{
	freopen("in.in", "r", stdin);
	freopen("out.out", "w", stdout);
}
}
using namespace IO;
#define int long long
#define F(i,x) for(int i=1;i<=x;i++)
const int N = 1e5;
struct fhq_tree {
	int ls, rs;
	int rnd, val, sz;
} tr[N];
int root = 0, cnt = 0;
void pushup(int u)
{
	tr[u].sz = tr[tr[u].rs].sz + tr[tr[u].ls].sz + 1;
}
void vsplit(int u, int v, int &x, int &y)
{
	if (!u)
	{
		x = y = 0;
		return ;
	}
	if (tr[u].val <= v)
	{
		x = u;
		vsplit(tr[u].rs, v, tr[u].rs, y);
	}
	else {
		y = u;
		vsplit(tr[u].ls, v, x, tr[u].ls);
	}
	pushup(u);

}
void ssplit(int u,int sz,int &x,int &y)
{
	if(!u) {
		x=y=0;
		return ;
	}
	if(sz>tr[tr[u].ls].sz)
	{
		x=u,ssplit(tr[u].rs,sz-tr[tr[u].ls].sz-1,tr[u].rs,y);
	}
	else y=u,ssplit(tr[u].ls,sz,x,tr[u].ls);
	pushup(u);
}
int newnode(int v)
{
	tr[++cnt].rnd=rand(),tr[cnt].val=v,tr[cnt].sz=1,tr[cnt].ls=tr[cnt].rs=0;
	return cnt;
}
int merge(int x, int y)
{
	if (!x || !y) return x + y;
	if (tr[x].rnd < tr[y].rnd)
	{
		tr[x].rs = merge(tr[x].rs, y);
		pushup(x);
		return x;
	}
	else {
		tr[y].ls = merge(x, tr[y].ls);
		pushup(y);
		return y;
	}
}
void insert(int v)
{
	int x, y;
	vsplit(root, v, x, y);
	root=merge(merge(x,newnode(v)),y);
}

void erase(int v)
{
	int x=0,y=0,z=0;
	vsplit(root,v,x,y);
	vsplit(x,v-1,x,z);
	z=merge(tr[z].ls,tr[z].rs);
	root=merge(merge(x,z),y);
}
int pre(int v)
{
	int x,y,cur;
	vsplit(root,v-1,x,y);
	cur=x;
	while(tr[cur].rs) cur=tr[cur].rs;
	root=merge(x,y);
	return tr[cur].val;
}
int suf(int v)
{
	int x,y,cur;
	vsplit(root,v,x,y);
	cur=y;
	while(tr[cur].ls) cur=tr[cur].ls;
	root=merge(x,y);
	return tr[cur].val;
}
int get_rank(int v)
{
	int x,y,ans;
	vsplit(root,v-1,x,y);
	ans=tr[x].sz;
	root=merge(x,y);
	return ans;
}
void init()
{
	srand(time(0));
	root=cnt=0;
	insert(-INT_MAX),insert(INT_MAX);
}
int kth(int k)
{
	++k;
	int x,y,cur;
	ssplit(root,k,x,y);
	cur=x;
	while(tr[cur].rs) cur=tr[cur].rs;
	root=merge(x,y);
	return tr[cur].val;
}
signed main() {
	//mc();
	init();
	int n;
	cin>>n;
	for(int i=1;i<=n;i++)
	{
		int opt;
		read(opt);
		if(opt==1)
		{
			int x;
			read(x);
			insert(x);
		}
		else if(opt==2)
		{
			int x;
			read(x);
			erase(x);
		}
		else if(opt==3)
		{
			int x;
			read(x);
			cout<<get_rank(x)<<endl;
		}
		else if(opt==4)
		{
			int pos;
			read(pos);
			cout<<kth(pos)<<endl;
		}
		else if(opt==5)
		{
			int x;
			read(x);
			cout<<pre(x)<<endl;
		}
		else if(opt==6)
		{
			int x;
			read(x);
			cout<<suf(x)<<endl;
		}
	}
	return 0;
}
posted @   gcomplex  阅读(9)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 地球OL攻略 —— 某应届生求职总结
· 提示词工程——AI应用必不可少的技术
· Open-Sora 2.0 重磅开源!
· 周边上新:园子的第一款马克杯温暖上架
点击右上角即可分享
微信分享提示