萌新刚学Splay,但用的是fhqTreap 求助
查看原帖
萌新刚学Splay,但用的是fhqTreap 求助
378555
danielqf楼主2022/4/5 22:18
#include <cstdio>
#include <cstdlib>
#include <ctime>

int val[100010], pri[100010], siz[100010], lft[100010], rit[100010], tot, root, n, min, c, k, a, b, delta, ans;

inline void pushup(int x) { siz[x] = siz[lft[x]] + siz[rit[x]] + 1; }

int merge(int x, int y) {
	if (!x || !y) return x + y;
	if (pri[x] > pri[y])
		return rit[x] = merge(rit[x], y), pushup(x), x;
	else
		return lft[y] = merge(x, lft[y]), pushup(y), y;
}

void split(int node, int k, int &x, int &y) {
	if (!node) return (void)(x = y = 0);
	if (k > val[node])
		x = node, split(rit[node], k, rit[x], y), pushup(x);
	else
		y = node, split(lft[node], k, x, lft[y]), pushup(y);
}

int kth(int k) {
	int x = root;
	while (1) {
		if (k <= siz[rit[x]]) x = rit[x];
		else if (k == siz[rit[x]] + 1) return x;
		else k -= siz[rit[x]] + 1, x = lft[x];
	}
}

int main() {
	srand(time(0));
	scanf("%d%d", &n, &min);
	while (n--) {
		while ((c = getchar()) < 'A' || c > 'Z') ;
		scanf("%d", &k);
		  if (c == 'I') {
			k -= delta;
			if (k >= min) {
				split(root, k, a, b),
				val[++tot] = k, pri[tot] = rand(), siz[tot] = 1,
				root = merge(merge(a, tot), b);
			}
		} if (c == 'A') {
			delta += k, min -= k;
		} if (c == 'S') {
			delta -= k, min += k,
			split(root, min - 1, a, root),
			ans += siz[a];
		} if (c == 'F') {
			if (k > siz[root]) puts("-1");
			else printf("%d\n", val[kth(k)] + delta);
		}
	}
	
	printf("%d", ans);
	return 0;
} 

详情

2022/4/5 22:18
加载中...