[模板] fhq Treap (无旋Treap)

[模板] 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\n",query_rank(temp));
        }else if(cmd==4){
            printf("%d\n",query_key(temp));
        }else if(cmd==5){
            printf("%d\n",maxless(temp));
        }else{
            printf("%d\n",mingreater(temp));
        }
    }

    system("pause");
    return 0;
}
posted @ 2020-11-15 21:38  popozyl  阅读(110)  评论(0编辑  收藏  举报