刚学 Treap,52 pts 求助
查看原帖
刚学 Treap,52 pts 求助
246099
dalao_see_me楼主2021/11/12 21:35

RT

#include <bits/stdc++.h>
using namespace std;
inline int read() {
	int x = 0, f = 1; char c = getchar();
	while (c < '0' || c > '9') {if (c == '-') f = -f; c = getchar();}
	while (c >= '0' && c <= '9') {x = x * 10 + (c ^ 48); c = getchar();}
	return x * f;
}
const int N = 1e5 + 5, INF = 1e9 + 5;
int q;
class Treap {
private:
	int tot;
	int v[N], siz[N], num[N], son[N][2], rd[N];
	inline void pushup(int x) {
		siz[x] = siz[son[x][0]] + siz[son[x][1]] + num[x];
	}
	inline void rotate(int &x, int d) {
		int k = son[x][d ^ 1];
		son[x][d ^ 1] = son[k][d];
		son[k][d] = x;
		pushup(x);
		pushup(k);
		x = k;
	}
public:
	int root;
	inline void ins(int &x, int p) {
		if (!x) {
			x = ++tot;
			siz[x] = num[x] = 1;
			v[x] = p;
			rd[x] = rand();
			return;
		}
		if (v[x] == p) {
			num[x]++;
			siz[x]++;
			return;
		}
		int d = (p > v[x]);
		ins(son[x][d], p);
		if (rd[x] < rd[son[x][d]]) rotate(x, d ^ 1);
		pushup(x);
	}
	inline void del(int &x, int p) {
		if (!x) return;
		if (p < v[x]) {
			del(son[x][0], p);
			return;
		}
		if (p > v[x]) {
			del(son[x][1], p);
			return;
		}
		if (!son[x][0] && !son[x][1]) {
			num[x]--; siz[x]--;
			if (num[x] == 0) x = 0;
		}
		else if (son[x][0] && !son[x][1]) {
			rotate(x, 1);
			del(son[x][1], p);
		}
		else if (!son[x][0] && son[x][1]) {
			rotate(x, 0);
			del(son[x][0], p);
		}
		else if (son[x][0] && son[x][1]){
			int d = (rd[son[x][0]] > rd[son[x][1]]);
			rotate(x, d);
			del(son[x][d], p);
		}
		pushup(x);
	}
	inline int Rank(int x, int p) {
		if (!x) return 0;
		if (v[x] == p) return siz[son[x][0]] + 1;
		if (v[x] > p) return Rank(son[x][0], p);
		return siz[son[x][0]] + num[x] + Rank(son[x][1], p);
	}
	inline int Find(int x, int p) {
		if (!x) return 0;
		if (siz[son[x][0]] >= p) return Find(son[x][0], p);
		else if (siz[son[x][0]] + num[x] < p) return Find(son[x][1], p - num[x] - siz[son[x][0]]);
		return v[x];
	}
	inline int Pre(int x, int p) {
		if (!x) return -INF;
		if (v[x] >= p) return Pre(son[x][0], p);
		return max(v[x], Pre(son[x][1], p));
	}
	inline int Nxt(int x, int p) {
		if (!x) return INF;
		if (v[x] <= p) return Nxt(son[x][1], p);
		return min(v[x], Nxt(son[x][0], p));
	}
} T;
int main() {
	srand(time(0));
	q = read();
	while (q--) {
		int op = read(), x = read();
		if (op == 1) T.ins(T.root, x);
		if (op == 2) T.del(T.root, x);
		if (op == 3) printf("%d\n", T.Rank(T.root, x));
		if (op == 4) printf("%d\n", T.Find(T.root, x));
		if (op == 5) printf("%d\n", T.Pre(T.root, x));
		if (op == 6) printf("%d\n", T.Nxt(T.root, x));
	}
	return 0;
}
2021/11/12 21:35
加载中...