namespace _Treap {
template<class T>
struct Node {
Node *child[2];
T val;
int rnd, cnt, size;
Node(T val) : val(val) {
cnt = size = 1;
rnd = rand();
child[0] = child[1] = nullptr;
}
void push() {
size = cnt;
if (child[0] != nullptr) {
size += child[0] -> size;
}
if (child[1] != nullptr) {
size += child[1] -> size;
}
}
};
template<class T>
struct Treap {
Node<T> *root = nullptr;
pair<Node<T>*, Node<T>*> split(Node<T> *cur, T key) {
if (cur == nullptr) return {nullptr, nullptr};
if (cur -> val <= key) {
auto temp = split(cur -> child[1], key);
cur -> child[1] = temp.first;
cur -> push();
return {cur, temp.second};
} else {
auto temp = split(cur -> child[0], key);
cur -> child[0] = temp.second;
cur -> push();
return {temp.first, cur};
}
}
tuple<Node<T>*, Node<T>*, Node<T>*> splitByRank(Node<T> *cur, int rank) {
if (cur == nullptr) return {nullptr, nullptr, nullptr};
int ls_size = cur -> child[0] == nullptr ? 0 : cur -> child[0] -> size;
if (rank <= ls_size) {
Node<T> *L, *mid, *R;
tie(L, mid, R) = splitByRank(cur -> child[0], rank);
cur -> child[0] = R;
cur -> push();
return {L, mid, cur};
} else if (rank <= ls_size + cur -> cnt) {
Node<T> *lt = cur -> child[0], *rt = cur -> child[1];
cur -> child[0] = cur -> child[1] = nullptr;
return {lt, cur, rt};
} else {
Node<T> *L, *mid, *R;
tie(L, mid, R) = splitByRank(cur -> child[1], rank - ls_size - cur -> cnt);
cur -> child[1] = L;
cur -> push();
return {cur, mid, R};
}
}
Node<T>* merge(Node<T> *a, Node<T> *b) {
if (a == nullptr) return b;
if (b == nullptr) return a;
if (a -> rnd < b -> rnd) {
a -> child[1] = merge(a -> child[1], b);
a -> push();
return a;
} else {
b -> child[0] = merge(a, b -> child[0]);
b -> push();
return b;
}
}
void insert(T x) {
auto temp = split(root, x);
auto l_tr = split(temp.first, x - 1);
Node<T> *res;
if (l_tr.second == nullptr) {
res = new Node(x);
} else {
l_tr.second -> cnt++;
l_tr.second -> push();
}
Node<T> *l_tr_combined = merge(l_tr.first, l_tr.second == nullptr ? res : l_tr.second);
root = merge(l_tr_combined, temp.second);
}
void erase(T x) {
auto temp = split(root, x);
auto l_tr = split(temp.first, x - 1);
if (l_tr.second -> cnt > 1) {
l_tr.second -> cnt--;
l_tr.second -> push();
l_tr.first = merge(l_tr.first, l_tr.second);
} else {
if (temp.first == l_tr.second) {
temp.first = nullptr;
}
delete l_tr.second;
l_tr.second = nullptr;
}
root = merge(l_tr.first, temp.second);
}
int rank(T val) {
return rank(root, val);
}
int rank(Node<T> *&cur, T val) {
auto temp = split(cur, val - 1);
int res = (temp.first == nullptr ? 0 : temp.first -> size) + 1;
root = merge(temp.first, temp.second);
return res;
}
T kth(int rank) {
return kth(root, rank);
}
T kth(Node<T>* &cur, int rank) {
Node<T> *L, *mid, *R;
tie(L, mid, R) = splitByRank(cur, rank);
T res = mid -> val;
root = merge(merge(L, mid), R);
return res;
}
T prev(T val) {
auto temp = split(root, val - 1);
T res = kth(temp.first, temp.first -> size);
root = merge(temp.first, temp.second);
return res;
}
T next(T val) {
auto temp = split(root, val);
int res = kth(temp.second, 1);
root = merge(temp.first, temp.second);
return res;
}
}; // Treap
// insert(T x) 插入 1 个 x
// erase(T x) 删除 1 个 x
// rank(T x) 查找 x 的排名
// kth(int x) 查找第 x 小
// prev(T x) 查找 x 的前驱
// next(T x) 查找 x 的后继
}
using _Treap::Treap;