Code:
#include<bits/stdc++.h>
#define endl '\n';
#define int long long
using namespace std;
const int N = 1e5 + 5;
int n;
struct Node{
int ls, rs;
int val, key;
int size;
}tree[N];
int tot, root;
inline int newnode(int val){
tot++;
tree[tot].val = val;
tree[tot].ls = 0;
tree[tot].rs = 0;
tree[tot].key = rand();
tree[tot].size = 1;
return tot;
}
inline void update(int node){
tree[node].size = tree[tree[node].ls].size + tree[tree[node].rs].size;
}
void split(int node, int val, int &r1, int &r2){
if(!node){
r1 = 0;
r2 = 0;
return ;
}
if(tree[node].val <= val){
r1 = node;
split(tree[node].rs, val, tree[node].rs, r2);
}
else{
r2 = node;
split(tree[node].ls, val, r1, tree[node].ls);
}
update(node);
}
int merge(int x, int y){
if(!x || !y){
return x + y;
}
if(tree[x].key > tree[y].key){
tree[x].rs = merge(tree[x].rs, y);
update(x);
return x;
}
else{
tree[y].ls = merge(x, tree[y].ls);
update(y);
return y;
}
}
int t1, t2, t3;
inline void insert(int val){
split(root, val, t1, t2);
root = merge(merge(t1, newnode(val)), t2);
}
inline void _delete(int val){
split(root, val, t1, t3);
split(t1, val - 1, t1, t2);
t2 = merge(tree[t2].ls, tree[t2].rs);
root = merge(merge(t1, t2), t3);
}
inline int _rank(int val){
split(root, val - 1, t1, t2);
int ans = tree[t1].size + 1;
root = merge(t1, t2);
return ans;
}
inline int query(int rank){
int node = root;
while(node){
if(tree[tree[node].ls].size + 1 == rank){
break;
}
else if(tree[tree[node].ls].size >= rank){
node = tree[node].ls;
}
else{
rank -= tree[tree[node].ls].size + 1;
node = tree[node].rs;
}
}
return tree[node].val;
}
inline int pre(int val){
split(root, val - 1, t1, t2);
int node = t1;
while(tree[node].rs){
node = tree[node].rs;
}
int ans = tree[node].val;
root = merge(t1, t2);
return ans;
}
inline int nxt(int val){
split(root, val, t1, t2);
int node = t2;
while(tree[node].ls){
node = tree[node].ls;
}
int ans = tree[node].val;
root = merge(t1, t2);
return ans;
}
void Solve(){
srand(time(0));
cin >> n;
while(n--){
int op;
cin >> op;
if(op == 1){
int x;
cin >> x;
insert(x);
}
else if(op == 2){
int x;
cin >> x;
_delete(x);
}
else if(op == 3){
int x;
cin >> x;
cout << _rank(x) << '\n';
}
else if(op == 4){
int x;
cin >> x;
cout << query(x) << '\n';
}
else if(op == 5){
int x;
cin >> x;
cout << pre(x) << '\n';
}
else{
int x;
cin >> x;
cout << nxt(x) << '\n';
}
}
}
signed main(){
Solve();
return 0;
}