题目传送门:https://www.luogu.com.cn/problem/P3369
模板:
1 #include<cstdio>
2 #include<cstring>
3 #include<cstdlib>
4 #include<iostream>
5 using namespace std;
6 const int MAXN = 100005;
7 const int MOD = 2147483647;
8
9 struct Node
10 {
11 int left; //左子树
12 int right; //右子树
13 int size; //大小
14 int val; //值
15 int key; //平衡种子
16 }tree[MAXN];
17
18 int root,tot;
19
20 int add(int val){
21 tot++;
22 tree[tot].size = 1;
23 tree[tot].val = val;
24 tree[tot].key = rand()%MOD;
25 tree[tot].left = 0;
26 tree[tot].right = 0;
27
28 return tot;
29 }
30
31 void update_root(int now){
32 int left,right;
33
34 left = tree[now].left;
35 right = tree[now].right;
36
37 tree[now].size = tree[left].size + tree[right].size + 1;
38 }
39
40 //拆分(now原treap,a左子树,b右子树,val值)
41 void split_new(int now, int &a, int &b, int val){
42 if(now == 0){
43 a = 0;
44 b = 0;
45 return;
46 }
47
48 if(tree[now].val <= val){//now左子树中的所有值都小于now,
49 a = now;
50 split_new(tree[now].right, tree[a].right, b, val);
51 }else{
52 b = now;
53 split_new(tree[now].left, a, tree[b].left, val);
54 }
55
56 update_root(now);
57 }
58
59 void merge_new(int &now, int a, int b){
60 if(a==0 || b==0){
61 now = a+b;
62 return;
63 }
64
65 //按照key值合并(堆性质)
66 if(tree[a].key<tree[b].key){
67 /**
68 * a树key值小于b树,那么b树属于a树的后代,因为b树恒大于a树,那么b树一定属于a树的右后代,
69 * a的左子树不变,直接赋给now,递归合并a的右子树和b
70 */
71 now = a;
72 merge_new(tree[now].right, tree[a].right, b);
73 }else{
74 now = b;
75 merge_new(tree[now].left, a, tree[b].left);
76 }
77
78 update_root(now);
79 }
80
81 void find_new(int now, int rank){//找第k大
82 while (tree[tree[now].left].size+1 != rank){
83 if(tree[tree[now].left].size >= rank){
84 now = tree[now].left;
85 }else{
86 rank -= tree[tree[now].left].size + 1;
87 now = tree[now].right;
88 }
89 }
90 cout << tree[now].val << "\n";
91 }
92
93 void insert_new(int val){
94 int x,y,z;
95
96 x = 0;
97 y = 0;
98 z = add(val);
99 split_new(root, x, y, val);
100 merge_new(x,x,z);
101 merge_new(root, x, y);
102 }
103
104 void del_new(int val){
105 int x,y,z;
106
107 x = y = z = 0;
108 split_new(root, x, y, val);
109 split_new(x, x, z, val-1);
110 merge_new(z, tree[z].left, tree[z].right);
111 merge_new(x, x, z);
112 merge_new(root, x, y);
113 }
114
115 void get_rank(int val){
116 int x,y;
117
118 x = y = 0;
119 split_new(root, x, y, val-1);
120 cout << tree[x].size + 1 << "\n";
121 merge_new(root,x,y);
122 }
123
124 void get_val(int rank){
125 find_new(root, rank);
126 }
127
128 void get_pre(int val){
129 int x,y;
130
131 x = y = 0;
132 split_new(root, x, y, val-1);
133 find_new(x, tree[x].size);
134 merge_new(root, x, y);
135 }
136
137 void get_next(int val){
138 int x,y;
139
140 x = y = 0;
141 split_new(root,x,y,val);
142 find_new(y,1);
143 merge_new(root,x,y);
144 }
145
146
147 int main(){
148
149 ios::sync_with_stdio(false);
150 cin.tie(0);
151
152 int n,op,x,i;
153 cin >> n;
154
155 memset(tree, 0, sizeof(tree));
156
157 add(MOD);
158 root = 1;
159 tree[root].size = 0;
160
161 for(i=0;i<n;i++){
162 cin >> op >> x;
163
164 switch (op){
165 case 1:
166 insert_new(x);
167 break;
168 case 2:
169 del_new(x);//删除x数(若有多个相同的数,则只删除一个)
170 break;
171 case 3:
172 get_rank(x);//查询x数的排名(排名定义为比当前数小的数的个数+1,若有多个相同的数则输出最小的排名)
173 break;
174 case 4:
175 get_val(x);//查询排名为x的数
176 break;
177 case 5:
178 get_pre(x);//求x的前驱(前驱定义为小于x,且最大的数)
179 break;
180 case 6:
181 get_next(x);//求x的后继(后继定义为大于x,且最小的数)
182 break;
183 }
184 }
185
186 return 0;
187 }