模板:Treap

#include <iostream>
#include <cstdio>
#include <cstring>
#include <stdlib.h>
#define INF 0x7fffffff
using namespace std;

inline int read(){
	int sum=0,f=1;char c=getchar();
	while(c>'9'||c<'0'){if(c=='-') f=-1;c=getchar();}
	while(c<='9'&&c>='0'){sum=sum*10+c-'0';c=getchar();}
	return sum*f;
}

struct tree{int l,r,size,cnt,val,dat;}t[100001];
int n,tot,root;

inline int New(int val){
	t[++tot].val=val;t[tot].dat=rand();
	t[tot].size=t[tot].cnt=1;
	return tot;
}

inline void update(int p){
	t[p].size=t[t[p].l].size+t[t[p].r].size+t[p].cnt;
}

inline void l_rotate(int &p){
	int q=t[p].l;
	t[p].l=t[q].r;t[q].r=p;p=q;
	update(t[p].r);update(p);
}

inline void r_rotate(int &p){
	int q=t[p].r;
	t[p].r=t[q].l;t[q].l=p;p=q;
	update(t[p].l);update(p);
}

inline void build(){
	New(-INF);New(INF);
	t[1].r=2;root=1;
	update(1);
}

inline void insert(int &p,int val){
	if(!p){p=New(val);return ;}
	if(t[p].val==val) t[p].cnt++;
	else insert(val<t[p].val? t[p].l:t[p].r,val);
	if(t[t[p].l].dat>t[p].dat) l_rotate(p);
	if(t[t[p].r].dat>t[p].dat) r_rotate(p);
	update(p);
}

inline void remove(int &p,int val){
	if(!p) return ;
	if(t[p].val==val){
		if(t[p].cnt>1){t[p].cnt--;update(p);return ;}
		if(!t[p].l&&!t[p].r){p=0;return ;}
		if(!t[p].r||t[t[p].l].dat>t[t[p].r].dat) l_rotate(p),remove(t[p].r,val);
		else r_rotate(p),remove(t[p].l,val);
		update(p);return ;
	}
	remove(val<t[p].val? t[p].l:t[p].r,val);update(p);
}

inline int getnext(int val){
	int p=root,ans=2;
	while(p){
		if(t[p].val==val){
			if(!t[p].r) break;
			p=t[p].r;while(t[p].l) p=t[p].l;
			ans=p;break;
		}
		if(t[p].val>val&&t[p].val<t[ans].val) ans=p;
		p=val<t[p].val? t[p].l:t[p].r;
	}
	return t[ans].val;
}

inline int getpre(int val){
	int p=root,ans=1;
	while(p){
		if(t[p].val==val){
			if(!t[p].l) break;
			p=t[p].l;while(t[p].r) p=t[p].r;
			ans=p;break;
		}
		if(t[p].val<val&&t[p].val>t[ans].val) ans=p;
		p=val<t[p].val? t[p].l:t[p].r;
	}
	return t[ans].val;
}

inline int getrank(int p,int val){
	if(t[p].val==val) return t[t[p].l].size;
	if(val<t[p].val) return getrank(t[p].l,val);
	return t[t[p].l].size+t[p].cnt+getrank(t[p].r,val);	
} 

inline int getval(int p,int rank){
	if(t[t[p].l].size>=rank) return getval(t[p].l,rank);
	if(t[t[p].l].size+t[p].cnt>=rank) return t[p].val;
	return getval(t[p].r,rank-t[t[p].l].size-t[p].cnt);
}

int main(){
	n=read();build();
	for(int i=1;i<=n;i++){
		int opt=read(),x=read();
		if(opt==1){insert(root,x);}
		else if(opt==2){remove(root,x);}
		else if(opt==3){printf("%d\n",getrank(root,x));}
		else if(opt==4){printf("%d\n",getval(root,x+1));}//因为有一个-INF所以要加一
		else if(opt==5){printf("%d\n",getpre(x));}
		else if(opt==6){printf("%d\n",getnext(x));}
	}
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值