版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/Cymbals/article/details/83212624
存一个。
#include<bits/stdc++.h>
using namespace std;
const int maxn = 1e5 + 5;
struct Splay {
//f[i]表示i的父结点,ch[i][0]表示i的左儿子,ch[i][1]表示i的右儿子.
//key[i]表示i的关键字(即结点i代表的那个数字),cnt[i]表示i结点的关键字出现的次数(相当于权值).
//size[i]表示包括i的这个子树的大小;sz为整棵树的大小,root为整棵树的根。
int ch[maxn][2], fa[maxn];
int size[maxn], cnt[maxn], key[maxn];
int root, sz;
void init() {
root = 0;
sz = 1;
}
void clear(int x) {
fa[x] = ch[x][0] = ch[x][1] = 0;
size[x] = cnt[x] = key[x] = 0;
}
bool get(int x) {
return ch[fa[x]][1] == x;
}
void update(int x) {
if(!x) {
return;
}
size[x] = cnt[x];
if(ch[x][0]) {
size[x] += size[ch[x][0]];
}
if(ch[x][1]) {
size[x] += size[ch[x][1]];
}
}
void rotate(int x) {
int old = fa[x], oldf = fa[old];
int tar = get(x);
ch[old][tar] = ch[x][tar ^ 1];
fa[ch[old][tar]] = old;
ch[x][tar ^ 1] = old;
fa[old] = x;
fa[x] = oldf;
if(oldf) {
ch[oldf][ch[oldf][1] == old] = x;
}
update(old);
update(x);
}
int newNode(int x, int f) {
fa[sz] = f;
ch[sz][0] = ch[sz][1] = 0;
root = sz;
size[sz] = cnt[sz] = 1;
key[sz] = x;
return sz++;
}
void splay(int x) {
for (int f; f = fa[x]; rotate(x))
if(fa[f]) {
if(get(x) == get(f)) {
rotate(f);
} else {
rotate(x);
}
}
root = x;
}
void insert(int x) {
if(root == 0) {
newNode(x, 0);
return;
}
int now = root, f = 0;
while(1) {
if(x == key[now]) {
++cnt[now];
update(now);
update(f);
splay(now);
break;
}
f = now;
now = ch[now][key[now] < x];
if(now == 0) {
int nq = newNode(x, f);
ch[f][key[f] < x] = nq;
update(f);
splay(nq);
break;
}
}
}
int find(int x) {
int now = root, ans = 0;
while(1) {
if(x < key[now]) {
now = ch[now][0];
} else {
ans += ch[now][0] ? size[ch[now][0]] : 0;
if(x == key[now]) {
splay(now);
return ans + 1;
}
ans += cnt[now];
now = ch[now][1];
}
}
}
int findx(int x) {
int now = root;
while(1) {
if(ch[now][0] && x <= size[ch[now][0]]) {
now = ch[now][0];
} else {
int tmp = (ch[now][0] ? size[ch[now][0]] : 0) + cnt[now];
if(x <= tmp) {
return key[now];
}
x -= tmp;
now = ch[now][1];
}
}
}
int pre() {
int now = ch[root][0];
while(ch[now][1]) {
now = ch[now][1];
}
return now;
}
int next() {
int now = ch[root][1];
while(ch[now][0]) {
now = ch[now][0];
}
return now;
}
void del(int x) {
find(x);
if(cnt[root] > 1) {
--cnt[root];
update(root);
return;
}
if(!ch[root][0] && !ch[root][1]) {
clear(root);
root = 0;
return;
}
int old = root;
if(!ch[root][0]) {
root = ch[root][1];
fa[root] = 0;
clear(old);
return;
}
if(!ch[root][1]) {
root = ch[root][0];
fa[root] = 0;
clear(old);
return;
}
splay(pre());
ch[root][1] = ch[old][1];
fa[ch[old][1]] = root;
clear(old);
update(root);
}
} sp;
int main() {
int n, opt, x;
scanf("%d", &n);
sp.init();
for (int i = 1; i <= n; ++i) {
scanf("%d%d", &opt, &x);
switch(opt) {
case 1:
sp.insert(x);
break;
case 2:
sp.del(x);
break;
case 3:
printf("%d\n", sp.find(x));
break;
case 4:
printf("%d\n", sp.findx(x));
break;
case 5:
sp.insert(x);
printf("%d\n", sp.key[sp.pre()]);
sp.del(x);
break;
case 6:
sp.insert(x);
printf("%d\n", sp.key[sp.next()]);
sp.del(x);
break;
}
}
return 0;
}