Treap 90 求调
查看原帖
Treap 90 求调
512724
wl2009_pretty_girl楼主2023/12/23 14:52
#include <bits/stdc++.h>
using namespace std;
const int N = 3e5 + 5;
int n, mn, ans;
struct Treap {
	int rt, tot, ans;
	int l[N], r[N], val[N], rnk[N], siz[N], cnt[N];
	void pushup(int x) { 
		siz[x] = siz[l[x]] + siz[r[x]] + cnt[x]; 
	}
	void rotate_left(int &x) {
		int tmp = r[x];
		r[x] = l[tmp], l[tmp] = x;
		siz[tmp] = siz[x], pushup(x);
		x = tmp;
	}
	void rotate_right(int &x) {
		int tmp = l[x];
		l[x] = r[tmp], r[tmp] = x;
		siz[tmp] = siz[x], pushup(x);
		x = tmp;
	}
	void update(int &x, int num) {
		if (!x) {
			x = ++tot;
			siz[x] = cnt[x] = 1;
			val[x] = num;
			rnk[x] = rand();
			return;
		}
		if (num == val[x]) siz[x]++, cnt[x]++;
		else if (num < val[x]) {
			update(l[x], num);
			pushup(x);
			if (rnk[l[x]] > rnk[x]) rotate_right(x);
		}
		else {
			update(r[x], num);
			pushup(x);
			if (rnk[r[x]] > rnk[x]) rotate_left(x);
		}
	}
	bool del(int &x, int num) {
		if (!x) return false;
		if (num == val[x]) {
			if (cnt[x] > 1) {
				siz[x]--, cnt[x]--;
				return true;
			}
			else if (!l[x] || !r[x]) {
				x = l[x] + r[x];
				return true;
			}
			else if (rnk[l[x]] > rnk[r[x]]) {
				rotate_right(x);
				return del(x, num);
			}
			else {
				rotate_left(x);
				del(x, num);
			}
		}
		bool f;
		if (num < val[x]) f = del(l[x], num);
		else f = del(r[x], num);
		pushup(x);
		return f;
	}
	int getnum(int x, int rnk) {
		if (!x) return 0;
		if (rnk <= siz[l[x]]) return getnum(l[x], rnk);
		if (rnk > siz[l[x]] + cnt[x]) return getnum(r[x], rnk - siz[l[x]] - cnt[x]);
		return val[x];
	}
	void getpre(int x, int num) {
		if (!x) return;
		if (val[x] < num) {
			ans = val[x];
			getpre(r[x], num);
		}
		else getpre(l[x], num);
	}
} T;
int main() {
	srand(time(0));
	scanf("%d%d", &n, &mn);
	int d = 0;
	while (n--) {
		char op;
		cin >> op;
		int x;
		scanf("%d", &x);
		if (op == 'I') {
			if (x < mn) continue;
			T.update(T.rt, x - d);
		}
		else if (op == 'A') d += x;
		else if (op == 'S') {
			d -= x;
			while (1) {
				T.ans = 0;
				T.getpre(T.rt, mn - d);
				if (!T.ans) break;
				ans++;
				T.del(T.rt, T.ans);
			}
		}
		else {
			if (x > T.siz[T.rt]) {
				puts("-1");
				continue;
			}
			printf("%d\n", T.getnum(T.rt, T.siz[T.rt] - x + 1) + d);
		}
	}
	printf("%d", ans);
	return 0;
}
2023/12/23 14:52
加载中...