所谓treap: tree+heap.
Treap在以关键码value构成二叉查找树的同时,还按优先级random来满足堆的性质。
它的维护方式同样是旋转,但只有左旋和右旋,且可以合写为一个rotate(int& p, bool r);
它支持普通平衡树的功能:插入、删除单个元素,询问整棵树的第k大
但是线段树能做到的区间操作,它一般不支持,但splay可以。
详细说明:
http://www.nocow.cn/index.php/Treap
模板题:hdu 4006
http://acm.hdu.edu.cn/showproblem.php?pid=4006
1 #include <iostream> 2 #include <stdio.h> 3 #include <string> 4 #include <algorithm> 5 #include <string.h> 6 #include <stdlib.h> 7 #include <ctime> 8 #define MAXN 100500 9 using namespace std; 10 11 struct Treap{ //大顶堆 12 int ch[MAXN][2], sz[MAXN]; 13 int rdm[MAXN], v[MAXN]; 14 int root, top1; 15 16 inline void init(){ 17 root = top1 = 0; 18 ch[0][0]=ch[0][1]=0, sz[0]=0; 19 rdm[0] = -1; 20 //srand(time(0)); 21 } 22 inline void newNode(int &p, int x){ 23 p = ++top1; 24 ch[p][0]=ch[p][1]=0, sz[p]=1; 25 rdm[p]=rand(), v[p]=x; 26 } 27 inline void Rotate(int &y, int r){ //r:(0,左);(1,右) 28 int x = ch[y][!r]; 29 ch[y][!r] = ch[x][r]; 30 ch[x][r] = y; 31 pushUp(y); 32 pushUp(x); 33 y = x; 34 } 35 inline void ins(int &p, int x){ 36 if(!p){ newNode(p, x); return; } 37 bool r = (x > v[p]); //!! 38 ins(ch[p][r], x); 39 if(rdm[ch[p][r]] > rdm[p]) 40 Rotate(p, !r); 41 pushUp(p); 42 } 43 inline void pushUp(int p){ 44 sz[p] = sz[ch[p][0]]+sz[ch[p][1]]+1; 45 } 46 inline int query(int p, int k){ 47 if(k==sz[ch[p][0]]+1) 48 return v[p]; 49 else if(k>sz[ch[p][0]]+1) 50 return query(ch[p][1], k-(sz[ch[p][0]]+1)); 51 else 52 return query(ch[p][0], k); 53 } 54 /* 暂未用到 55 inline void del(int &p, int x){ 56 if(!p) return ; 57 if(x < v[p]) del(ch[p][0], x); 58 else if(x > v[p]) del(ch[p][1], x); 59 else if(ch[p][0] || ch[p][1]){ 60 int r = rdm[ch[p][0]]<=rdm[ch[p][1]]; 61 Rotate(p, !r); 62 del(ch[p][!r], x); 63 }else 64 p = 0; 65 pushUp(p); 66 } 67 void print(int p){ 68 if(!p) return ; 69 print(ch[p][0]); 70 printf("%d ", v[p]); 71 print(ch[p][1]); 72 } 73 */ 74 }tp; 75 //hdu 4006 76 int main() 77 { 78 int n, k; 79 while(cin >> n >> k){ 80 char s[5]; 81 int x, cnt=0; 82 tp.init(); 83 while(n--){ 84 scanf("%s", s); 85 if(s[0]=='I'){ 86 scanf("%d", &x); 87 tp.ins(tp.root, x); 88 }else 89 printf("%d ", tp.query(tp.root, tp.sz[tp.root]+1-k)); 90 } 91 } 92 return 0; 93 }