rt
/** {
* problem: Splay
* site: \
* author: _Z_F_R_
* date: 2023-10-29 21:41:46
**/
#include <bits/stdc++.h>
#define ll long long
using namespace std;
const int N = 100005;
struct Splay_Tree
{
struct tNode
{
int fa, lc, rc;
int val, cnt, size;
}tree[N << 1];
int root, cntnode;
bool isrc(int x)
{
return tree[tree[x].fa].rc == x;
}
void Update(int x)
{
tree[x].size = tree[tree[x].lc].size + tree[tree[x].rc].size + tree[x].cnt;
}
void Zag(int x)
{
int fa = tree[x].fa;
int gfa = tree[fa].fa;
bool sg = isrc(fa);
tree[fa].rc = tree[x].lc;
if(tree[fa].rc)
tree[tree[fa].rc].fa = fa;
tree[fa].fa = x, tree[x].lc = fa, tree[x].fa = gfa;
if(gfa)
{
if(sg)
tree[gfa].rc = x;
else
tree[gfa].lc = x;
}
}
void Zig(int x)
{
int fa = tree[x].fa;
int gfa = tree[fa].fa;
bool sg = isrc(fa);
tree[fa].lc = tree[x].rc;
if(tree[fa].lc)
tree[tree[fa].lc].fa = fa;
tree[fa].fa = x, tree[x].rc = fa, tree[x].fa = gfa;
if(gfa)
{
if(sg)
tree[gfa].rc = x;
else
tree[gfa].lc = x;
}
}
void Rotate(int x)
{
int fa = tree[x].fa;
bool sf = isrc(x);
if(sf)
Zag(x);
else
Zig(x);
Update(fa), Update(x);
}
void Splay(int x, int goal)
{
if(goal == 0)
root = x;
while(true)
{
int fa = tree[x].fa;
int gfa = tree[fa].fa;
if(fa == goal)
break;
if(gfa != goal)
{
if(isrc(x) == isrc(fa))
Rotate(fa);
else
Rotate(x);
}
Rotate(x);
}
}
int Find_Pos(int x, int val)
{
if(val < tree[x].val && tree[x].lc)
return Find_Pos(tree[x].lc, val);
if(val > tree[x].val && tree[x].rc)
return Find_Pos(tree[x].rc, val);
return x;
}
int Find_Num(int rank)
{
int x = root, rrank = rank;
while(true)
{
if(rrank <= tree[tree[x].lc].size)
x = tree[x].lc;
else
{
rrank -= tree[tree[x].lc].size;
if(rrank <= tree[x].cnt)
return tree[x].val;
rrank -= tree[x].cnt, x = tree[x].rc;
}
}
}
int Find_Rank(int val)
{
int x = root, ans = 0;
while(tree[x].val != val)
{
if(!x)
return ans + 1;
if(val < tree[x].val)
x = tree[x].lc;
else
ans += tree[tree[x].lc].size + tree[x].cnt, x = tree[x].rc;
}
if(tree[x].lc)
ans += tree[tree[x].lc].size;
return ans + 1;
}
int tans;
void Dfs_Pre(int x)
{
if(tree[x].rc)
Dfs_Pre(tree[x].rc);
if(tans)
return ;
tans = tree[x].val;
}
int Find_Pre(int x, int val, bool is_rc)
{
tans = 0;
if(!is_rc)
return Find_Pre(tree[x].fa, val, tree[tree[x].fa].rc == x);
if(tree[x].val < val)
return tree[x].val;
if(tree[x].lc)
{
Dfs_Pre(tree[x].lc);
return tans;
}
return Find_Pre(tree[x].fa, val, tree[tree[x].fa].rc == x);
}
void Dfs_Nxt(int x)
{
if(tree[x].lc)
Dfs_Nxt(tree[x].lc);
if(tans)
return ;
tans = tree[x].val;
}
int Find_Nxt(int x, int val, bool is_lc)
{
tans = 0;
if(!is_lc)
return Find_Nxt(tree[x].fa, val, tree[tree[x].fa].lc == x);
if(tree[x].val > val)
return tree[x].val;
if(tree[x].rc)
{
Dfs_Nxt(tree[x].rc);
return tans;
}
return Find_Nxt(tree[x].fa, val, tree[tree[x].fa].lc == x);
}
void Add_Node(int val, int fa)
{
cntnode++;
tree[cntnode].lc = tree[cntnode].rc = 0;
tree[cntnode].size = tree[cntnode].cnt = 1;
tree[cntnode].fa = fa, tree[cntnode].val = val;
if(fa)
{
if(val < tree[fa].val)
tree[fa].lc = cntnode;
else
tree[fa].rc = cntnode;
}
}
void Add(int val)
{
int x = root, fa = 0;
while(x && tree[x].val != val)
if(tree[x].val > val)
fa = x, x = tree[x].lc;
else
fa = x, x = tree[x].rc;
if(!x)
{
Add_Node(val, fa);
Splay(cntnode, 0);
return ;
}
tree[x].cnt++;
}
void Del(int val)
{
int prex = Find_Pos(root, Find_Pre(Find_Pos(root, val), val, true));
int nxtx = Find_Pos(root, Find_Nxt(Find_Pos(root, val), val, true));
Splay(prex, 0);
Splay(nxtx, prex);
Print();
if(tree[tree[nxtx].lc].cnt > 1)
{
tree[tree[nxtx].lc].cnt--;
Splay(tree[nxtx].lc, 0);
}
else
tree[nxtx].lc = 0;
Update(nxtx), Update(prex);
}
void Print()
{
printf("%d\n", root);
int i;
for(i = 1; i <= cntnode; i++)
printf("%d : fa : %d lc : %d rc : %d cnt : %d val : %d size : %d\n", i, tree[i].fa, tree[i].lc, tree[i].rc, tree[i].cnt, tree[i].val, tree[i].size);
}
}bst;
int main()
{
freopen("P3369_4.in", "r", stdin);
int n;
scanf("%d", &n);
while(n--)
{
int op, val;
scanf("%d %d", &op, &val);
if(op == 1)
bst.Add(val);
else if(op == 2)
bst.Del(val);
else if(op == 3)
printf("%d\n", bst.Find_Rank(val));
else if(op == 4)
printf("%d\n", bst.Find_Num(val));
else if(op == 5)
printf("%d\n", bst.Find_Pre(bst.Find_Pos(bst.root, val), val, true));
else
printf("%d\n", bst.Find_Nxt(bst.Find_Pos(bst.root, val), val, true));
// bst.Print();
}
}