Bzoj3224普通平衡树
Description
您需要写一种数据结构(可参考题目标题),来维护一些数,其中需要提供以下操作:
1. 插入x数
2. 删除x数(若有多个相同的数,因只删除一个)
3. 查询x数的排名(若有多个相同的数,因输出最小的排名)
4. 查询排名为x的数
5. 求x的前驱(前驱定义为小于x,且最大的数)
6. 求x的后继(后继定义为大于x,且最小的数)
Input
第一行为n,表示操作的个数,下面n行每行有两个数opt和x,opt表示操作的序号(1<=opt<=6)
Output
对于操作3,4,5,6每行输出一个数,表示对应答案
Sample Input
10
1 106465
4 1
1 317721
1 460929
1 644985
1 84185
1 89851
6 81968
1 492737
5 493598
1 106465
4 1
1 317721
1 460929
1 644985
1 84185
1 89851
6 81968
1 492737
5 493598
Sample Output
106465
84185
492737
HINT
1.n的数据范围:n<=100000
2.每个数的数据范围:[-1e7,1e7]
1 #include <iostream> 2 #include <cstdio> 3 #include <algorithm> 4 #include <cstdlib> 5 using namespace std; 6 const int MAXN=1000001; 7 const int INF=1e9; 8 struct Treap 9 { 10 int ch[2],key,tms,size,dat; 11 }treap[MAXN]; 12 int root,tot; 13 int T,op,n; 14 inline int cmp(int x,int tar) 15 { 16 if(tar==treap[x].dat) return -1; 17 return (tar<treap[x].dat?0:1); 18 } 19 inline void maintain(int x) 20 { 21 treap[x].size=treap[x].tms; 22 if(treap[x].ch[0]) treap[x].size+=treap[treap[x].ch[0]].size; 23 if(treap[x].ch[1]) treap[x].size+=treap[treap[x].ch[1]].size; 24 } 25 inline void rotate(int &x,int d) 26 { 27 int p=treap[x].ch[d^1]; 28 treap[x].ch[d^1]=treap[p].ch[d]; 29 treap[p].ch[d]=x; 30 maintain(x); 31 maintain(p); 32 x=p; 33 } 34 void ins(int &x,int tar) 35 { 36 if(!x) 37 { 38 tot++; 39 treap[tot].key=rand(); 40 treap[tot].dat=tar; 41 treap[tot].tms=1; 42 treap[tot].size=1; 43 x=tot; 44 return; 45 } 46 int d=cmp(x,tar); 47 if(d==-1) treap[x].tms++; 48 else 49 { 50 ins(treap[x].ch[d],tar); 51 if(treap[treap[x].ch[d]].key>treap[x].key) rotate(x,d^1); 52 } 53 maintain(x); 54 } 55 void del(int &x,int tar) 56 { 57 int d=cmp(x,tar); 58 if(d==-1) 59 { 60 if(treap[x].tms>1) treap[x].tms--; 61 else 62 { 63 if(!treap[x].ch[0]&&!treap[x].ch[1]) x=0; 64 else if(!treap[x].ch[0]&&treap[x].ch[1]) x=treap[x].ch[1]; 65 else if(treap[x].ch[0]&&!treap[x].ch[1]) x=treap[x].ch[0]; 66 else 67 { 68 int t=(treap[treap[x].ch[0]].key>treap[treap[x].ch[1]].key?1:0); 69 rotate(x,t); 70 del(treap[x].ch[t],tar); 71 } 72 } 73 } 74 else del(treap[x].ch[d],tar); 75 maintain(x); 76 } 77 inline int GetPre(int x,int tar) 78 { 79 int con=-INF; 80 while(x) 81 { 82 int d=cmp(x,tar); 83 if(d==-1) x=treap[x].ch[0]; 84 else if(d) 85 { 86 con=max(con,treap[x].dat); 87 x=treap[x].ch[1]; 88 } 89 else x=treap[x].ch[0]; 90 } 91 return con; 92 } 93 inline int GetNext(int x,int tar) 94 { 95 int con=INF; 96 while(x) 97 { 98 int d=cmp(x,tar); 99 if(d==-1) x=treap[x].ch[1]; 100 else if(d) x=treap[x].ch[1]; 101 else 102 { 103 con=min(con,treap[x].dat); 104 x=treap[x].ch[0]; 105 } 106 } 107 return con; 108 } 109 int GetRank(int x,int tar) 110 { 111 int d=cmp(x,tar); 112 if(d==-1) return treap[treap[x].ch[0]].size+1; 113 else if(d) return treap[treap[x].ch[0]].size+treap[x].tms+GetRank(treap[x].ch[1],tar); 114 else return GetRank(treap[x].ch[0],tar); 115 } 116 int GetKth(int x,int k) 117 { 118 if(k<=treap[treap[x].ch[0]].size) return GetKth(treap[x].ch[0],k); 119 k-=treap[treap[x].ch[0]].size+treap[x].tms; 120 if(k<=0) return treap[x].dat; 121 else return GetKth(treap[x].ch[1],k); 122 } 123 int main(int argc, char *argv[]) 124 { 125 scanf("%d",&T); 126 for(int i=1;i<=T;i++) 127 { 128 scanf("%d%d",&op,&n); 129 if(op==1) ins(root,n); 130 else if(op==2) del(root,n); 131 else if(op==3) printf("%d\n",GetRank(root,n)); 132 else if(op==4) printf("%d\n",GetKth(root,n)); 133 else if(op==5) printf("%d\n",GetPre(root,n)); 134 else if(op==6) printf("%d\n",GetNext(root,n)); 135 } 136 return 0; 137 }
叶子的离去,是风的追求,还是树的不挽留?