【Treap】[CQBZOJ2803]普通平衡树
粘模板
#include<cstdio>
#include<algorithm>
using namespace std;
#define MAXN 500000
int n,pre,bk;
struct node{
int val,pri,cnt,lsize,rsize;
node *ls,*rs;
}treap_tree[MAXN+10],*tcnt=treap_tree,*root;
void Read(int &x){
char c;
bool f=0;
while(c=getchar(),c!=EOF){
if(c=='-')
f=1;
if(c>='0'&&c<='9'){
x=c-'0';
while(c=getchar(),c>='0'&&c<='9')
x=x*10+c-'0';
if(f)
x=-x;
return;
}
}
}
void Rotate_left(node *&a){
node *b=a->rs;
a->rs=b->ls;
b->ls=a;
a->rsize=b->lsize;
b->lsize=a->lsize+a->rsize+a->cnt;
a=b;
}
void Rotate_right(node *&a){
node *b=a->ls;
a->ls=b->rs;
b->rs=a;
a->lsize=b->rsize;
b->rsize=a->lsize+a->rsize+a->cnt;
a=b;
}
void del(node *&p,int val){
if(p->val==val){
if(p->cnt>1){
p->cnt--;
return;
}
if(!p->ls||!p->rs){
if(p->ls)
p=p->ls;
else
p=p->rs;
return;
}
if(p->ls->pri<p->rs->pri){
Rotate_right(p);
p->rsize--;
del(p->rs,val);
}
else{
Rotate_left(p);
p->lsize--;
del(p->ls,val);
}
}
else if(val<p->val){
p->lsize--;
del(p->ls,val);
}
else{
p->rsize--;
del(p->rs,val);
}
}
void Treap_insert(node *&p,int val){
if(!p){
p=++tcnt;
p->cnt=1;
p->val=val;
p->ls=p->rs=NULL;
p->pri=rand();
return;
}
if(val>p->val){
p->rsize++;
Treap_insert(p->rs,val);
if(p->rs->pri<p->pri)
Rotate_left(p);
}
else if(val<p->val){
p->lsize++;
Treap_insert(p->ls,val);
if(p->ls->pri<p->pri)
Rotate_right(p);
}
else
p->cnt++;
}
int find_pos(node *&p,int val){
if(!p)
return 0;
if(p->val>val)
return find_pos(p->ls,val);
if(p->val<val)
return p->lsize+p->cnt+find_pos(p->rs,val);
return p->lsize;
}
void find_pre(node *&p,int val){
if(!p)
return;
if(p->val<val){
pre=p->val;
find_pre(p->rs,val);
}
else
find_pre(p->ls,val);
}
void find_bk(node *&p,int val){
if(!p)
return;
if(p->val>val)
{
bk=p->val;
find_bk(p->ls,val);
}
else
find_bk(p->rs,val);
}
void pos_find(node *&p,int pos){
if(pos<p->lsize)
pos_find(p->ls,pos);
else if(pos>=p->lsize+p->cnt)
pos_find(p->rs,pos-p->lsize-p->cnt);
else
printf("%d\n",p->val);
}
int main()
{
int i,a,b;
srand(2015111820);
Read(n);
for(i=1;i<=n;i++){
Read(a),Read(b);
if(a==1)
Treap_insert(root,b);
else if(a==2)
del(root,b);
else if(a==3)
printf("%d\n",find_pos(root,b)+1);
else if(a==4)
pos_find(root,b-1);
else if(a==5){
find_pre(root,b);
printf("%d\n",pre);
}
else{
find_bk(root,b);
printf("%d\n",bk);
}
}
}