[模板] fhq Treap (無旋Treap)
阿新 • • 發佈:2020-11-16
[模板] fhq Treap (無旋Treap)
#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; }