[模板] fhq Treap (无旋Treap)
模板题AcWing253.普通平衡树
教程视频
#include <cstdio>
#include <algorithm>
#include <queue>
using namespace std;
const int N = 1e5+5;
struct Node{
int lson,rson; // 左右子结点
int key; // 值
int w; // 随机权重
int size; // 自身+子树 大小
};
int idx; // 索引分配器
int root;
Node tree[N]; // fhq treap
inline int create_node(int key){
tree[++idx].key = key;
tree[idx].w = rand();
tree[idx].size = 1;
return idx;
}
inline void push_up(int rt){
tree[rt].size = tree[tree[rt].lson].size + tree[tree[rt].rson].size + 1;
}
inline void split(int rt,int key,int &ansl,int &ansr){
if(!rt){
ansl = ansr = 0;
}else{
if(tree[rt].key <= key){
ansl = rt;
split(tree[rt].rson,key,tree[rt].rson,ansr);
}else{
ansr = rt;
split(tree[rt].lson,key,ansl,tree[rt].lson);
}
push_up(rt);
}
}
inline int merge(int ansl,int ansr){
// ansl 中的所有key一定都小于 ansr中的所有key
if(!ansl || !ansr){
return ansl + ansr;
}else{
if(tree[ansl].w < tree[ansr].w){ // 按照小根堆处理,父结点的w小于所有子结点的w
tree[ansl].rson = merge(tree[ansl].rson,ansr); // 传参顺序不能反
push_up(ansl);
return ansl;
}else{
tree[ansr].lson = merge(ansl,tree[ansr].lson); // 传参顺序不能反
push_up(ansr);
return ansr;
}
}
}
inline void insert(int key){
int ansl=0,ansr=0;
split(root,key,ansl,ansr);
root = merge(merge(ansl,create_node(key)),ansr);
}
inline void remove(int key){
int x,y,z;
split(root,key,x,z);
split(x,key-1,x,y);
y = merge(tree[y].lson,tree[y].rson);
root = merge(merge(x,y),z);
}
inline int query_rank(int key){ // 查询key的排名(比key小的数的个数+1)
int ans,x,y;
split(root,key-1,x,y);
ans = tree[x].size+1;
root = merge(x,y);
return ans;
}
inline int query_key(int rank){
int ptr = root;
while(ptr){
if(tree[tree[ptr].lson].size+1==rank){
return tree[ptr].key;
}else if(tree[tree[ptr].lson].size+1>rank){
ptr = tree[ptr].lson;
}else{
rank -= tree[tree[ptr].lson].size+1;
ptr = tree[ptr].rson;
}
}
return -1;
}
inline int maxless(int key){
int ans,x,y;
split(root,key-1,x,y);
int ptr = x;
while(tree[ptr].rson){
ptr = tree[ptr].rson;
}
ans = tree[ptr].key;
root = merge(x,y);
return ans;
}
inline int mingreater(int key){
int ans,x,y;
split(root,key,x,y);
int ptr = y;
while(tree[ptr].lson){
ptr = tree[ptr].lson;
}
ans = tree[ptr].key;
root = merge(x,y);
return ans;
}
int main(){
int n,cmd,temp;
scanf("%d",&n);
for(int i = 1; i <= n; ++i){
scanf("%d%d",&cmd,&temp);
if(cmd==1){
insert(temp);
}else if(cmd==2){
remove(temp);
}else if(cmd==3){
printf("%d
",query_rank(temp));
}else if(cmd==4){
printf("%d
",query_key(temp));
}else if(cmd==5){
printf("%d
",maxless(temp));
}else{
printf("%d
",mingreater(temp));
}
}
system("pause");
return 0;
}