模板:有旋treap
有旋转的treap,其实rotate比较难理解
没关系,上板子:
题目还是普通平衡树
#include<iostream>
#include<cstdio>
#include<algorithm>
#define MAXN 100005
using namespace std;
int n,opt,x,root=0,np;
struct node{
int ch[MAXN][2],val[MAXN],size[MAXN],cnt[MAXN],prior[MAXN];
void update(int now){
size[now]=size[ch[now][0]]+size[ch[now][1]]+cnt[now];
}
void rotate(int &now,int dir){
int son=ch[now][dir^1];
ch[now][dir^1]=ch[son][dir];
ch[son][dir]=now;
update(now);
update(now=son);
}
void insert(int &now,int x){
if(!now){
now=++np;
size[now]=cnt[now]=1;
prior[now]=rand();
val[now]=x;
return ;
}
size[now]++;
if(val[now]==x){
cnt[now]++;
return ;
}
int d=x>val[now];
insert(ch[now][d],x);
if(prior[ch[now][d]]<prior[now]) rotate(now,d^1);
}
void remove(int &now,int num){
if(!now) return;
if(val[now]==num){
if(cnt[now]>1){
size[now]--;
cnt[now]--;
return;
}
if(!ch[now][0]||!ch[now][1]){
now=ch[now][0]+ch[now][1];
return;
}
int d=prior[ch[now][1]]<prior[ch[now][0]];
rotate(now,d^1);
remove(now,num);
return;
}
size[now]--;
int d=num>val[now];
remove(ch[now][d],num);
}
int get_rank(int now, int num){
if(!now) return 0;
if(num==val[now]) return size[ch[now][0]]+1;
int d=num>val[now];
if(d) return size[ch[now][0]]+cnt[now]+get_rank(ch[now][1],num);
return get_rank(ch[now][0],num);
}
int get_k(int now,int k){
while(now){
if(k<=size[ch[now][0]]) now=ch[now][0];
else if(k>size[ch[now][0]]+cnt[now]) k-=size[ch[now][0]]+cnt[now],now=ch[now][1];
else return val[now];
}
}
int get_pre(int now,int num){
if(!now) return -0x7fffffff;
if(num<=val[now]) return get_pre(ch[now][0],num);
return max(val[now],get_pre(ch[now][1],num));
}
int get_next(int now,int num){
if(!now) return 0x7fffffff;
if(num>=val[now]) return get_next(ch[now][1],num);
return min(val[now],get_next(ch[now][0],num));
}
}treap;
int main(){
scanf("%d",&n);
while(n--){
scanf("%d%d",&opt,&x);
if(opt==1) treap.insert(root,x);
else if(opt==2) treap.remove(root, x);
else if(opt==3) printf("%d\n",treap.get_rank(root,x));
else if(opt==4) printf("%d\n",treap.get_k(root,x));
else if(opt==5) printf("%d\n",treap.get_pre(root,x));
else if(opt==6) printf("%d\n",treap.get_next(root,x));
}
return 0;
}

浙公网安备 33010602011771号