逗号打成分号搞了好久 艹艹艹
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<iostream>
#include<queue>
#define SF scanf
#define PF printf
using namespace std;
typedef long long LL;
inline int read() {
int x=0, f=1; char ch=getchar();
while(ch<'0' || ch>'9') { if(ch=='-') f=-1; ch=getchar(); }
while('0'<=ch && ch<='9') { x=x*10+ch-'0'; ch=getchar(); }
return x*f;
}
const int MAXN = 500000;
int n, ans, root;
struct Treap {
int l[MAXN+10], r[MAXN+10], sz[MAXN+10], rnd[MAXN+10], val[MAXN+10], cnt[MAXN+10];
int ncnt;
void up(int x) {
sz[x] = sz[l[x]] + sz[r[x]] + cnt[x];
}
void lturn(int &x) {
int t = r[x]; r[x] = l[t]; l[t] = x;
sz[t] = sz[x]; up(x); x= t;
}
void rturn(int &x) {
int t =l[x]; l[x] = r[t]; r[t] = x;
sz[t] = sz[x]; up(x); x = t;
}
int NewNode(int key) {
ncnt++;
sz[ncnt] = cnt[ncnt] = 1;
val[ncnt] = key; rnd[ncnt] = rand();
return ncnt;
}
void ins(int &x, int key) {
if(!x) {
x = NewNode(key);
return ;
}
sz[x]++;
if(val[x] == key) cnt[x]++;
else if(key > val[x]) {
ins(r[x], key);
if(rnd[r[x]] < rnd[x]) lturn(x);
}
else {
ins(l[x], key);
if(rnd[l[x]] < rnd[x]) rturn(x);
}
}
void del(int &x, int key) {
if(!x) return ;
if(val[x] == key) {
if(cnt[x] > 1) { cnt[x]--; sz[x]--; return ;}
if(l[x]*r[x] == 0) x = l[x]+r[x];
else if(rnd[l[x]] < rnd[r[x]]) rturn(x), del(x, key);
else lturn(x), del(x, key);
}
else if(key > val[x])
sz[x]--, del(r[x], key);
else
sz[x]--, del(l[x], key);
}
int Find_rank(int x, int key) {
if(!x) return 0;
if(val[x] == key) return sz[l[x]]+1;
else if(key > val[x])
return sz[l[x]]+cnt[x]+Find_rank(r[x], key);
else return Find_rank(l[x], key);
}
int Find_val(int x, int k) {
if(!x) return 0;
if(k <= sz[l[x]]) return Find_val(l[x], k);
else if(k > sz[l[x]]+cnt[x])
return Find_val(r[x], k-sz[l[x]]-cnt[x]);
return val[x];
}
void Find_pre(int x, int key) {
if(!x) return ;
if(val[x] < key) {
ans = x; Find_pre(r[x], key);
}
else Find_pre(l[x], key);
}
void Find_nex(int x, int key) {
if(!x) return ;
if(val[x] > key) {
ans = x; Find_nex(l[x], key);
}
else Find_nex(r[x], key);
}
} tp;
int main() {
for (n = read(); n; --n) {
int op = read(), x = read();
switch (op) {
case 1: tp.ins(root, x); break;
case 2: tp.del(root, x); break;
case 3: printf("%d\n", tp.Find_rank(root, x)); break;
case 4: printf("%d\n", tp.Find_val(root, x)); break;
case 5: ans = 0; tp.Find_pre(root, x); PF("%d\n", tp.val[ans]); break;
case 6: ans = 0; tp.Find_nex(root, x); PF("%d\n", tp.val[ans]); break;
}
}
return 0;
}