#include<iostream>
#include<cstdio>
#include<cmath>
using namespace std;
struct splay_tree{
#define side_of(x) (x == tr[tr[x].fa].ch[1])
#define INF (int)INFINITY
struct node{
int fa, ch[2];//父节点 子节点
int val, cnt, siz;//权值 数量 子树大小
}tr[(int)1e6+10];
int rt, idx;//根结点编号 总结点数
inline void pushup(int p){tr[p].siz = tr[p].cnt + tr[tr[p].ch[0]].siz + tr[tr[p].ch[1]].siz;}
//计算子树大小信息
inline int new_node(const int &val, const int fa = 0){//新建节点
++idx;
tr[idx].fa = fa;
tr[idx].cnt = 1;
tr[idx].val = val;
return idx;
}
inline void rotate(const int &x){//旋转
int y = tr[x].fa;
int z = tr[y].fa;
bool sx = side_of(x), sy = side_of(y);
tr[y].ch[sx] = tr[x].ch[sx^1];
if(tr[x].ch[sx^1]) tr[tr[x].ch[sx^1]].fa = y;
tr[x].ch[sx^1] = y;
tr[y].fa = x;
if(z) tr[z].ch[sy] = x;
tr[x].fa = z;
pushup(y), pushup(x);
}
inline void splay(int x){
for(int f = tr[x].fa; f = tr[x].fa, f; rotate(x))
if(tr[f].fa) rotate(side_of(f) == side_of(x) ? f : x);
rt = x;
}
inline void Insert(const int &val){//插入
int p = rt, fa = 0;
if(!rt) return rt = new_node(val), void();
while(1)
{
if(tr[p].val == val)
{
++tr[p].cnt;
pushup(p), pushup(fa);
splay(p);
return;
}
fa = p, p = tr[fa].ch[val>tr[fa].val];
if(!p)
{
tr[fa].ch[val>tr[fa].val] = new_node(val, fa);
pushup(p), pushup(fa);
splay(idx);
return;
}
}
}
inline int rk(const int &val){//求排名
int p = rt, ret = 0, fa = 0;
while(1){
// printf("p=%d\n", p);
if(!p) return splay(fa), ret+1;
if(val < tr[p].val) fa = p, p = tr[p].ch[0];
else {
ret += tr[tr[p].ch[0]].siz;
if(tr[p].val == val) return splay(p), ret + 1;
fa = p, p = tr[p].ch[1];
}
}
}
inline int suc(const int &val){//前驱
// show();
rk(val);
if(tr[rt].val < val) return tr[rt].val;
int p = tr[rt].ch[0];
if(!p) return -INF;
while(tr[p].ch[1]) p = tr[p].ch[1];
splay(p);
return tr[p].val;
}
inline int nxt(const int &val){//后继
rk(val);
// show();
if(tr[rt].val > val) return tr[rt].val;
int p = tr[rt].ch[1];
if(!p) return INF;
while(tr[p].ch[0]) p = tr[p].ch[0];
splay(p);
return tr[p].val;
}
inline void Delete(const int &val){//删除
rk(val);
const int x = tr[rt].ch[0];
const int y = tr[rt].ch[1];
if(!x||!y) return rt = (x|y), void();
rt = x;
suc(tr[rt].val);
tr[rt].ch[1] = y;
pushup(y), pushup(rt);
}
inline int kth(int k){//第k大元素
int p = rt, fa = 0;
while(1)
{
if(!p) return tr[fa].val;
if(tr[tr[p].ch[0]].siz < k)
{
k -= tr[p].cnt + tr[tr[p].ch[0]].siz;
if(k <= 0) return splay(p), tr[p].val;
fa = p, p = tr[p].ch[1];
}
else fa = p, p = tr[p].ch[0];
}
}
void print(int p){//辅助调试 以中序遍历顺序打印
if(tr[p].ch[0]) print(tr[p].ch[0]);
printf("id:%d ls:%d rs:%d val:%d siz:%d\n", p, tr[p].ch[0], tr[p].ch[1], tr[p].val, tr[p].siz);
if(tr[p].ch[1]) print(tr[p].ch[1]);
}
void show(){//调试
printf("root:%d\n", rt);
print(rt);
puts("");
}
}Splay;
int main(){
int n;
scanf("%d", &n);
int op, x;
while(n--)
{
scanf("%d %d", &op, &x);
switch(op)
{
case 1: Splay.Insert(x);break;
case 2: Splay.Delete(x);break;
case 3: printf("%d\n", Splay.rk(x));break;
case 4: printf("%d\n", Splay.kth(x));break;
case 5: printf("%d\n", Splay.suc(x));break;
case 6: printf("%d\n", Splay.nxt(x));break;
}
}
return 0;
}
/*
4
1 10
1 20
1 30
3 21
16
1 5
1 4
1 3
1 2
1 1
1 6
1 7
1 11
1 9
1 10
1 8
1 12
1 13
1 14
1 15
5 11
*/
rt
出现WA&TLE
望各路好心大佬指点迷津