// This Code was made by Chinese_zjc_.
#include <bits/stdc++.h>
// #define debug
unsigned seed = std::chrono::system_clock::now().time_since_epoch().count();
std::mt19937 Rand(0);
struct node
{
const node *lson, *rson;
int v;
unsigned w;
std::size_t size;
node(int v_) : lson(), rson(), v(v_), w(Rand()), size(1) {}
#define size(x) ((x) ? (x)->size : 0)
void pushup()
{
size = 1 + size(lson) + size(rson);
}
};
class treap
{
const node *root;
const node *merge(const node *A, const node *B) const
{
if (!A)
return B;
if (!B)
return A;
node *res;
if (A->w < B->w)
{
res = new node(*A);
res->rson = merge(A->rson, B);
}
else
{
res = new node(*B);
res->lson = merge(A, B->lson);
}
res->pushup();
return res;
}
std::pair<node *, node *> split(const node *X, int v) const
{
std::pair<node *, node *> res;
if (!X)
return res;
if (X->v < v)
{
res.first = new node(*X);
std::pair<node *, node *> tmp = split(X->rson, v);
res.first->rson = tmp.first;
res.second = tmp.second;
res.first->pushup();
}
else
{
res.second = new node(*X);
std::pair<node *, node *> tmp = split(X->lson, v);
res.second->lson = tmp.second;
res.first = tmp.first;
res.second->pushup();
}
return res;
}
std::size_t rank_(const node *now, int v) const
{
if (!now)
return 0;
if (now->v < v)
return size(now->lson) + 1 + rank_(now->rson, v);
else
return rank_(now->lson, v);
}
int find_(const node *now, std::size_t rk) const
{
if (!now)
return INT_MAX;
if (size(now->lson) <= rk)
rk -= size(now->lson);
else
return find_(now->lson, rk);
if (!rk)
return now->v;
return find_(now->rson, rk - 1);
}
public:
explicit treap(const node *root_) : root(root_) {}
treap insert(int v)
{
std::pair<node *, node *> tmp = split(root, v);
return treap(merge(tmp.first, merge(new node(v), tmp.second)));
}
treap erase(int v)
{
std::pair<node *, node *> tmp = split(root, v);
node *l = tmp.first;
tmp = split(tmp.second, v + 1);
if (!tmp.first)
return treap(merge(l, tmp.second));
return treap(merge(merge(l, tmp.first->lson), merge(tmp.first->rson, tmp.second)));
}
std::size_t rank(int v) const
{
return rank_(root, v);
}
int find(std::size_t rk) const
{
return find_(root, rk);
}
};
std::vector<treap> a;
int n;
signed main()
{
std::ios::sync_with_stdio(false);
a.push_back(treap(nullptr));
a.back() = a.back().insert(-(1ll << 31) + 1);
a.back() = a.back().insert(+(1ll << 31) - 1);
std::cin >> n;
for (int i = 1, v, opt, x; i <= n; ++i)
{
std::cin >> v >> opt >> x;
switch (opt)
{
case 1:
a.push_back(a[v].insert(x));
break;
case 2:
a.push_back(a[v].erase(x));
break;
case 3:
a.push_back(a[v]);
std::cout << a[i].rank(x) << std::endl;
break;
case 4:
a.push_back(a[v]);
std::cout << a[i].find(x) << std::endl;
break;
case 5:
a.push_back(a[v]);
std::cout << a[i].find(a[i].rank(x) - 1) << std::endl;
break;
case 6:
a.push_back(a[v]);
std::cout << a[i].find(a[i].rank(x + 1)) << std::endl;
break;
}
// std::cout << i << std::endl;
// a[i].visit();
// a[0].visit();
}
return 0;
}
用的指针,可能看着比较怪