Splay板子求调,P3369 【模板】普通平衡树
  • 板块学术版
  • 楼主LolaPeppa
  • 当前回复0
  • 已保存回复0
  • 发布时间2024/7/19 10:42
  • 上次更新2024/7/19 11:29:44
查看原帖
Splay板子求调,P3369 【模板】普通平衡树
1314900
LolaPeppa楼主2024/7/19 10:42

58pts,WA+TLE

#include <iostream>
#include <cstdio>

using namespace std;

const int N = 100010;

int n, nn, root;
int cnt[N], sz[N], ch[N][2], f[N], val[N];

int get(int p) {
	return ch[f[p]][1] == p;
}

void pushUp(int p) {
	sz[p] = sz[ch[p][0]] + sz[ch[p][1]] + cnt[p];
}

void rotate(int x) {
	int y = f[x], z = f[y], d = get(x), w = ch[x][d ^ 1];
	f[w] = y;
	ch[y][d] = w;
	f[x] = z;
	if (z) ch[z][get(y)] = x;
	f[y] = x;
	ch[x][d ^ 1] = y;
	pushUp(y);
	pushUp(x);
}

void splay(int x) {
	while (f[x]) {
		int y = f[x], z = f[y];
		if (z) {
		    if (get(x) == get(y)) rotate(y);
		    else rotate(x);
		}
		rotate(x);
	}
	root = x;
}

void insert(int x) {
	int cur = root, old = 0;
	while (cur && val[cur] != x) {
		old = cur;
		cur = ch[cur][val[cur] < x];
	}
	if (cur != 0) {
		cnt[cur] -- ;
		sz[cur] -- ;
		return;
	} else {
		cur = ++ nn;
		if (old) ch[old][val[old] < x] = cur;
		cnt[cur] = sz[cur] = 1;
		val[cur] = x;
		f[cur] = old;
	}
	splay(cur);
}

pair<int, bool> ran(int x) {
	int cur = root, ans = 0;
	while (cur) {
	    if (val[cur] > x) cur = ch[cur][0];
		else if (val[cur] == x) {
			splay(cur);
			return {sz[ch[cur][0]] + 1, true};
		}
		else {
			ans += sz[ch[cur][0]] + cnt[cur];
			cur = ch[cur][1];
		}
	}
	return {ans + 1, false};
}

int kth(int x) {
	int cur = root;
	while (true) {
		if (sz[ch[cur][0]] >= x) cur = ch[cur][0];
		else if (sz[ch[cur][0]] + cnt[cur] >= x) {
		    splay(cur);
			return val[cur];
		} else {
			x -= sz[ch[cur][0]] + cnt[cur];
			cur = ch[cur][1];
		}
	}
}

int pre() {
	int cur = ch[root][0];
	while (ch[cur][1]) cur = ch[cur][1];
	return cur;
}

int suc() {
	int cur = ch[root][1];
	while (ch[cur][0]) cur = ch[cur][0];
	return cur;
}

void del(int x) {
	if (ran(x).second == false) return;
	if (cnt[root] > 1) {
		cnt[root] -- ;
		sz[root] -- ;
		return;
	}
	if (ch[root][0] == 0) {
		root = ch[root][1];
		f[root] = 0;
		return;
	}
	if (ch[root][1] == 0) {
		root = ch[root][0];
		f[root] = 0;
		return;
	}
	int newRoot = pre(), oldRoot = root;
	splay(newRoot);
	ch[root][1] = ch[oldRoot][1];
	f[ch[oldRoot][1]] = root;
	pushUp(root);
	
}

int main() {
	scanf("%d", &n);
	while (n -- ) {
		int opt, x;
		scanf("%d%d", &opt, &x);
		if (opt == 1) insert(x);
		else if (opt == 2) del(x);
		else if (opt == 3) printf("%d\n", ran(x).first);
		else if (opt == 4) printf("%d\n", kth(x));
		else if (opt == 5) {
			insert(x);
			printf("%d\n", val[pre()]);
			del(x);
		} else {
			insert(x);
			printf("%d\n", val[suc()]);
			del(x);
		}
	}
	return 0;
}
2024/7/19 10:42
加载中...