RT...
#include <cstdio>
#include <cstring>
#include <iostream>
#include <cmath>
#include <algorithm>
#include <string>
#define maxn 10010
using namespace std;
const long long INF = 2147483647;
//自制 二叉平衡树
struct node {
int ls = -1;
int rs = -1;
int val;
int size = 0;
int cnt;
} x[maxn];
int bnt = 0;
void add(int v, int num = 0) { //num表示当前有值的结点的的序号,v表示添加的值
if (bnt == 0) { //检测bnt,事实上日报恰恰少了这一步
x[bnt].val = v;
x[bnt].size = 1;
x[bnt].cnt = 1;
bnt++;
return; //根节点创建完成,退出
} else { //不是
x[num].size++;
if (x[num].val == v) { //如果值相等
x[num].cnt++; //计数器++
return;
}
if (x[num].val > v) { //如果这个节点的值大于给的值,说明需要走左边
if (x[num].ls == -1) { //这里与日报不一样,我检测有没有子树
x[bnt].val = v;
x[bnt].size = 1;
x[bnt].cnt = 1;
x[num].ls = bnt; //建立关系
bnt++;
} else {
add(v, x[num].ls); //有左子树,就下放到左边的结点
}
} else { //如果这个节点的值小于给的值,走右边
if (x[num].rs == -1) { //这里与日报不一样,我检测有没有子树
x[bnt].val = v;
x[bnt].size = 1;
x[bnt].cnt = 1;
x[num].rs = bnt; //建立关系
bnt++;
} else {
add(v, x[num].rs); //有左子树,就下放到左边的结点
}
}
}
}
int GetPre(int num, int v, int ans) { //num表示将要进行比较的结点,v表示需要查找的,ans表示备份的答案
if (x[num].val >= v) {
if (x[num].ls == -1) {
return ans; //返回答案备份
} else {
return GetPre(x[num].ls, v, ans);
}
} else {
if (x[num].rs == -1) {
return x[num].val;
} else {
return GetPre(x[num].rs, v, x[num].val);
}
}
}
int GetNext(int num, int v, int ans) { //num表示将要进行比较的结点,v表示需要查找的,ans表示备份的答案
if (x[num].val <= v) {
if (x[num].rs == -1) {
return ans; //返回答案备份
} else {
return GetNext(x[num].rs, v, ans);
}
} else {
if (x[num].ls == -1) {
return x[num].val;
} else {
return GetNext(x[num].ls, v, x[num].val);
}
}
}
int root_size = x[0].size - x[x[0].rs].size;
int GetValByRank(int num, int rank) { //num指当前比较的结点,rank指排名
if (rank == 0) {
return INF;
}
if (rank == root_size) {
return x[0].val;
}
if (x[x[num].ls].size >= rank) { //先查看普遍值偏小的子树的大小是否足够排名了
return GetValByRank(x[num].ls, rank); //跑到左子树的左子树里面查
}
if (x[x[num].ls].size + x[num].cnt >= rank) { //左子树与我当前这个结点有的个数的值加起来大于它
return x[num].val; //直接返回吧
}
return GetValByRank(x[num].rs, rank - x[x[num].ls].size - x[num].cnt);
}
int GetRankByVal(int num, int val) { //变量意义参上
if (val == x[num].val) {
return x[x[num].ls].size + 1;
}
if (val < x[num].val) {
return GetRankByVal(x[num].ls, val);
}
return GetRankByVal(x[num].rs, val) + x[x[num].ls].size + x[num].cnt;
}
int q, opt, x1;
int main() {
cin >> q;
for (int i = 0; i < q; i++) {
cin >> opt >> x1;
switch (opt) {
case 1: {
cout << GetRankByVal(0, x1) << endl;
break;
}
case 2: {
cout << GetValByRank(0, x1) << endl;
break;
}
case 3: {
cout << GetPre(0, x1, -INF) << endl;
break;
}
case 4: {
cout << GetNext(0, x1, INF) << endl;
break;
}
case 5: {
add(x1);
break;
}
}
}
return 0;
}