#include <bits/stdc++.h>

using namespace std;

const int maxn = 100000 + 5;

int psz; // pool size
int key[maxn], pri[maxn], siz[maxn], lc[maxn], rc[maxn];

int node(int k) {
 	int u = ++psz;
 	key[u] = k, pri[u] = rand(), siz[u] = 1, lc[u] = rc[u] = 0;
 	return u;
}

void maintain(int u) {
	siz[u] = siz[lc[u]] + siz[rc[u]] + 1;
}

void split(int u, int k, int &l, int &r) {
	if (u == 0) {
		r = l = 0;
		return;
	}
	if (key[u] >= k) {
		split(lc[u], k, l, lc[u]);
		r = u;
	} else {
		split(rc[u], k, rc[u], r);
		l = u;
	}
	maintain(u);
}

int merge(int u, int v) {
	if (u == 0 || v == 0) return u + v;
	if (pri[u] > pri[v]) {
		rc[u] = merge(rc[u], v);
		maintain(u);
		return u;
	} else {
		lc[v] = merge(u, lc[v]);
		maintain(v);
		return v;
	}
}

void insert(int &root, int k) {
	int l, r;
	split(root, k, l, r);
	root = merge(merge(l, node(k)), r);
}

void erase(int &root, int k) {
	int l, r, u;
	split(root, k, l, r);
	split(r, k + 1, u, r);
	root = merge(merge(l, merge(lc[u], rc[u])), r);
}

int Rank(int root, int x) {
	int u = root, ret = 0;
	while (u) {
		if (key[u] >= x) u = lc[u];
		else ret += siz[lc[u]] + 1, u = rc[u];
	}
	return ret;
}

int Kth(int root, int k) {
	int u = root;
	while (u) {
		if (siz[lc[u]] == k) return key[u];
		if (siz[lc[u]] > k) u = lc[u];
		else k -= siz[lc[u]] + 1, u = rc[u];
	}
	return -1;
}

int Prev(int root, int x) {
	return Kth(root, Rank(root, x) - 1);
}

int Next(int root, int x) {
	return Kth(root, Rank(root, x + 1));
}

int main() {
	int T;
	cin >> T;
	
	int root = 0;
	while (T--) {
		int opt, x;
		cin >> opt >> x;
		if (opt == 1) {
			insert(root, x);
		} else if (opt == 2) {
			erase(root, x);
		} else if (opt == 3) {
			cout << Rank(root, x) + 1 << '\n';
		} else if (opt == 4) {
			cout << Kth(root, x - 1) << '\n';
		} else if (opt == 5) {
			cout << Prev(root, x) << '\n';
		} else {
			cout << Next(root, x) << '\n';
		}
	}
}

0 comments

No comments so far...