voidconnect(int u, int f, int d){ if (u) fa[u] = f; ch[f][d] = u; }
voidrotate(int u){ int f = fa[u], ff = fa[f], du = dir(u); if (!f) return; int df = dir(f); connect(u, ff, df), connect(ch[u][du ^ 1], f, du), connect(f, u, du ^ 1); pushup(f), pushup(u); if (f == root) root = u; }
voidcheck(int u){ if (!u || !col[u]) return; if (root == u) { col[u] ^= 1; } elseif (col[fa[u]]) { int f = fa[u]; int df = dir(f), ff = fa[f], du = dir(u), v = ch[ff][df ^ 1]; if (col[v]) { col[f] = col[v] = 0; col[ff] = 1; } else { if (du == df) { rotate(f); col[ff] = 1, col[f] = 0; } else { rotate(u); rotate(u); col[ff] = 1, col[u] = 0; } } } }
intgetred(int u, int d){ if (ch[u][d] && col[ch[u][d]]) return d; elseif (ch[u][d ^ 1] && col[ch[u][d ^ 1]]) return d ^ 1; return-1; }
voidmaintain(int u){ int f = fa[u]; if (u == root) { root = 0; return; } int du = dir(u), v = ch[f][du ^ 1]; ch[f][du] = 0; fa[u] = 0; while (true) { if (!v) return; if (!col[f] && col[v]) { swap(col[f], col[v]); rotate(v); v = ch[f][du ^ 1]; } elseif (!col[f] && !col[v] && getred(v, 0) == -1) { col[v] = 1; u = f; if (u == root) return; f = fa[u], du = dir(u), v = ch[f][du ^ 1]; } elseif (col[f] && !col[v] && getred(v, 0) == -1) { swap(col[f], col[v]); return; } else { int dv = dir(v); if (getred(v, dv) == dv) { col[v] = col[f]; col[ch[v][dv]] = col[f] = 0; rotate(v); } else { col[ch[v][dv ^ 1]] = col[f]; col[f] = 0; int son = ch[v][dv ^ 1]; rotate(son); rotate(son); } return; } } }
voidinsert(int &u, int f, int x){ if (!u) { u = node(f, x); check(u); return; } ++size[u]; if (x >= val[u]) insert(ch[u][1], u, x); else insert(ch[u][0], u, x); check(u); }
intgetnext(int u){ if (!ch[u][1]) { u = ch[u][0]; if (!u) return0; while (ch[u][1]) u = ch[u][1]; } else { u = ch[u][1]; while (ch[u][0]) u = ch[u][0]; } return u; }
voiddel(int &u, int x){ if (!u) return; size[u]--; if (val[u] == x) { int next = getnext(u); if (!next) { if (col[u]) { ch[fa[u]][dir(u)] = 0; fa[u] = 0; } else { maintain(u); } } else { int v = next; while (fa[v] != u) { v = fa[v]; size[v]--; } swap(val[u], val[next]); del(next, x); } } elseif (x > val[u]) { del(ch[u][1], x); } else del(ch[u][0], x); }
intrank(int x){ int u = root, ans = 0; while (u) { if (val[u] < x) ans += size[ch[u][0]] + 1, u = ch[u][1]; else u = ch[u][0]; } return ans + 1; }
intfind(int k){ int u = root; while (u) { if (size[ch[u][0]] + 1 >= k) { if (size[ch[u][0]] < k) return val[u]; else u = ch[u][0]; } else k -= size[ch[u][0]] + 1, u = ch[u][1]; } return-1; }
intpre(int x){ int u = root, ans = -INF; while (u) { if (val[u] < x && val[u] > ans) ans = val[u]; if (val[u] < x) u = ch[u][1]; else u = ch[u][0]; } return ans; }
intnext(int x){ int u = root, ans = INF; while (u) { if (val[u] > x && val[u] < ans) ans = val[u]; if (val[u] > x) u = ch[u][0]; else u = ch[u][1]; } return ans; } } T;
voidMain(){ int n; cin >> n; for (int cas = 1; cas <= n; cas++) { int op, x; cin >> op >> x; if (op == 1) T.insert(T.root, 0, x); if (op == 2) T.del(T.root, x); if (op == 3) cout << T.rank(x) << '\n'; if (op == 4) cout << T.find(x) << '\n'; if (op == 5) cout << T.pre(x) << '\n'; if (op == 6) cout << T.next(x) << '\n'; } }