求助Splay 36分
查看原帖
求助Splay 36分
448887
cancan123456楼主2022/1/23 09:42
#include <cstdio>
using namespace std;
const int N = 100005;
int v[N], ch[N][2], fa[N], cnt[N], size[N];
int root, tot;
void outputSplay() {
	printf("--------------------\n");
	printf("当前节点数: %d\n", tot);
	printf("根: %d\n", root);
	for (int i = 1; i <= tot; i++) {
		printf("值: %d, 父亲: %d, 左节点: %d, 右节点: %d\n", v[i], fa[i], ch[i][0], ch[i][1]);
	}
	printf("--------------------\n");
}
void Maintain(int x) {
	size[x] = size[ch[x][0]] + size[ch[x][1]] + cnt[x];
}
void LeftRotate(int x) {
	int y = ch[x][1], z = fa[x];
	ch[x][1] = ch[y][0];
	if (ch[x][1] != 0) {
		fa[ch[x][1]] = x;
	}
	fa[y] = z;
	if (z != 0) {
		if (ch[z][0] == x) {
			ch[z][0] = y;
		} else {
			ch[z][1] = y;
		}
	}
	fa[x] = y;
	ch[y][0] = x;
	Maintain(x);
	Maintain(y);
}
void RightRotate(int x) {
	int y = ch[x][0], z = fa[x];
	ch[x][0] = ch[y][1];
	if (y != 0) {
		fa[y] = x;
	}
	fa[y] = z;
	if (z != 0) {
		if (ch[z][0] == x) {
			ch[z][0] = y;
		} else {
			ch[z][1] = y;
		}
	}
	fa[x] = y;
	ch[y][1] = x;
	Maintain(x);
	Maintain(y);
}
void Rotate(int x) {
	if (ch[fa[x]][0] == x) {
		RightRotate(fa[x]);
	} else {
		LeftRotate(fa[x]);
	}
}
void Splay(int x, int & root = root) {
	while (fa[x] != 0) {
		int y = fa[x];
		int z = fa[y];
		if (z == 0) {
			Rotate(x);
		} else {
			if ((ch[y][0] == x && ch[z][0] == y) || (ch[y][1] == x && ch[z][1] == y)) {
				Rotate(y);
			} else {
				Rotate(x);
			}
			Rotate(x);
		}
	}
	root = x;
}
void Insert(int x) {
	if (root == 0) {
		tot++;
		v[tot] = x;
		size[tot] = cnt[tot] = 1;
		root = tot;
	} else {
		int cur = root, f = 0;
		while (true) {
			if (v[cur] == x) {
				cnt[cur]++;
				break;
			}
			f = cur;
			if (x < v[cur]) {
				if (ch[cur][0] == 0) {
					tot++;
					v[tot] = x;
					fa[tot] = f;
					size[tot] = cnt[tot] = 1;
					ch[f][0] = tot;
					cur = tot;
					break;
				} else {
					cur = ch[cur][0];
				}
			} else {
				if (ch[cur][1] == 0) {
					tot++;
					v[tot] = x;
					fa[tot] = f;
					size[tot] = cnt[tot] = 1;
					ch[f][1] = tot;
					cur = tot;
					break;
				} else {
					cur = ch[cur][1];
				}
			}
		}
		Maintain(f);
		Maintain(cur);
		Splay(cur);
	}
}
int Rank(int x) {
	int ans = 0;
	int cur = root;
	while (true) {
		if (x < v[cur]) {
			cur = ch[cur][0];
		} else {
			ans += size[ch[cur][0]];
			if (x == v[cur]) {
				Splay(cur);
				return ans + 1;
			}
			ans += cnt[cur];
			cur = ch[cur][1];
		}
	}
}
int Kth(int k) {
	int cur = root;
	while (true) {
		if (ch[cur][0] != 0 && k <= size[ch[cur][0]]) {
			cur = ch[cur][0];
		} else {
			k -= cnt[cur] + size[ch[cur][0]];
			if (k <= 0) {
				Splay(cur);
				return v[cur];
			}
			cur = ch[cur][1];
		}
	}
}
int Merge(int x, int y) {
	if (x != 0 && y != 0) {
		int cur = x;
		while (ch[cur][1] != 0) {
			cur = ch[cur][1];
		}
		Splay(cur, x);
		ch[x][1] = y;
		fa[y] = x;
		return x;
	} else if (x == 0 && y != 0) {
		return y;
	} else if (x != 0 && y == 0) {
		return x;
	} else {
		return 0;
	}
}
void Delete(int x) {
	Rank(x);
	if (cnt[root] > 1) {
		cnt[root]--;
	} else {
		fa[ch[root][0]] = fa[ch[root][1]] = 0;
		root = Merge(ch[root][0], ch[root][1]);
	}
}
int Pre(int x) {
	Insert(x);
	int cur = ch[root][0];
	while (ch[cur][1] != 0) {
		cur = ch[cur][1];
	}
	Delete(x);
	return v[cur];
}
int Suffix(int x) {
	Insert(x);
	int cur = ch[root][1];
	while (ch[cur][0] != 0) {
		cur = ch[cur][0];
	}
	Delete(x);
	return v[cur];
}
int main() {
	int n;
	scanf("%d", &n);
	for (int op, x, i = 1; i <= n; i++) {
		scanf("%d %d", &op, &x);
		if (op == 1) {
			Insert(x);
		} else if (op == 2) {
			Delete(x);
		} else if (op == 3) {
			printf("%d\n", Rank(x));
		} else if (op == 4) {
			printf("%d\n", Kth(x));
		} else if (op == 5) {
			printf("%d\n", Pre(x));
		} else {
			printf("%d\n", Suffix(x));
		}
	}
	return 0;
}
2022/1/23 09:42
加载中...