替罪羊树求助
查看原帖
替罪羊树求助
448887
cancan123456楼主2022/11/16 22:38
#include <cstdio>
using namespace std;
const int N = 100005;
const double alpha = 0.75;
// 未删除节点:                          1     wn[p]  1
// 已删除节点:                          1       0    0
int cnt, root, val[N], ch[N][2], wn[N], s[N], sz[N], sd[N];
int new_node(int x) {
	cnt++;
	val[cnt] = x;
	ch[cnt][0] = ch[cnt][1] = 0;
	wn[cnt] = 1;
	s[cnt] = sz[cnt] = sd[cnt] = 1;
	return cnt;
}
void push_up(int p) {
	s[p] = s[ch[p][0]] + s[ch[p][1]] + 1;
	sz[p] = sz[ch[p][0]] + sz[ch[p][1]] + wn[p];
	sd[p] = sd[ch[p][0]] + sd[ch[p][0]] + (wn[p] != 0 ? 1 : 0);
}
int max(int a, int b) {
	return a > b ? a : b;
}
bool need_rebuild(int p) {
	return wn[p] != 0 && (alpha * s[p] <= max(s[ch[p][0]], ch[p][1]) || sd[p] <= alpha * s[p]);
}
int point[N], len;
void flatten(int p) {
	if (p != 0) {
		flatten(ch[p][0]);
		if (wn[p] > 0) {
			len++;
			point[len] = p;
		}
		flatten(ch[p][1]);
	}
}
int build(int l, int r) {
	if (l > r) {
		return 0;
	} else {
		int mid = (l + r) / 2;
		ch[point[mid]][0] = build(l, mid - 1);
		ch[point[mid]][1] = build(mid + 1, r);
		push_up(point[mid]);
		return point[mid];
	}
}
int rebuild(int p) {
	len = 0;
	flatten(p);
	return build(1, len);
}
void insert(int & p, int x) {
	if (p == 0) {
		p = new_node(x);
	} else {
		if (x == val[p]) {
			wn[p]++;
		} else if (x < val[p]) {
			insert(ch[p][0], x);
		} else {
			insert(ch[p][1], x);
		}
		push_up(p);
		if (need_rebuild(p)) {
			p = rebuild(p);
		}
	}
}
void del(int & p, int x) {
	if (x == val[p]) {
		wn[p]--;
	} else if (x < val[p]) {
		del(ch[p][0], x);
	} else {
		del(ch[p][1], x);
	}
	push_up(p);
	if (need_rebuild(p)) {
		p = rebuild(p);
	}
}
int rk(int p, int x) {
	if (p == 0) {
		return 0;
	} else {
		if (x == val[p]) {
			return sz[ch[p][0]];
		} else if (x < val[p]) {
			return rk(ch[p][0], x);
		} else {
			return sz[ch[p][1]] + wn[p] + rk(ch[p][1], x);
		}
	}
}
int kth(int p, int x) {
	if (sz[ch[p][0]] <= x && x < sz[ch[p][0]] + wn[p]) {
		return val[p];
	} else if (sz[ch[p][0]] + wn[p] <= x) {
		return kth(ch[p][1], x - sz[ch[p][0]] - wn[p]);
	} else {
		return kth(ch[p][0], x);
	}
}
int pre(int x) {
	return kth(root, rk(root, x) - 1);
}
int suc(int x) {
	return kth(root, rk(root, x + 1));
}
int main() {
	int n;
	scanf("%d", &n);
	for (int op, x; n != 0; n--) {
		scanf("%d %d", &op, &x);
		if (op == 1) {
			insert(root, x);
		} else if (op == 2) {
			del(root, x);
		} else if (op == 3) {
			printf("%d\n", rk(root, x) + 1);
		} else if (op == 4) {
			printf("%d\n", kth(root, x - 1));
		} else if (op == 5) {
			printf("%d\n", pre(x));
		} else {
			printf("%d\n", suc(x));
		}
	}
	return 0;
}

全是 MLE

2022/11/16 22:38
加载中...