比赛 数据结构模板题 评测结果 AAAAAAAAAA
题目名称 普通平衡树 最终得分 100
用户昵称 LikableP 运行时间 0.323 s
代码语言 C++ 内存使用 2.12 MiB
提交时间 2025-04-15 19:05:13
显示代码纯文本
#include <cstdio>
#include <cstdlib>

const int MAXN = 1e5 + 10;
const int INF = 0x7fffffff;

struct NODE {
	int ls, rs;
	int val, cnt;
	int siz;
	int qwq;
} node[MAXN];

int n;
int root, nodeNum;

int New(int val) {
	node[++nodeNum].val = val;
	node[nodeNum].qwq = rand();
	node[nodeNum].cnt = 1;
	node[nodeNum].siz = 1;
	return nodeNum;
}

void Update(int root) {
	node[root].siz = node[node[root].ls].siz + node[root].cnt + node[node[root].rs].siz;
	return ;
}

void Build(int &root) {
	root = New(-INF);
	node[root].rs = New(INF);
	Update(root);
	return ;
}

void zig(int &root) {
	int lson = node[root].ls;
	node[root].ls = node[lson].rs;
	node[lson].rs = root;
	root = lson;
	Update(node[root].rs);
	Update(root);
	return ;
}

void zag(int &root) {
	int rson = node[root].rs;
	node[root].rs = node[rson].ls;
	node[rson].ls = root;
	root = rson;
	Update(node[root].ls);
	Update(root);
	return ;
}

void Insert(int &root, int val) {
	if (node[root].val == val) {
		node[root].cnt++;
		Update(root);
		return ;
	}
	if (!root) {
		root = New(val);
		return ;
	}
	if (val < node[root].val) {
		Insert(node[root].ls, val);
		if (node[node[root].ls].qwq > node[root].qwq) zig(root);
	} else {
		Insert(node[root].rs, val);
		if (node[node[root].rs].qwq > node[root].qwq) zag(root);
	}
	Update(root);
	return ;
}

void Remove(int &root, int val) {
	if (node[root].val == val) {
		if (node[root].cnt == 1) {
			if (node[root].ls || node[root].rs) {
				if (!node[root].rs || node[node[root].rs].qwq < node[node[root].ls].qwq) {
					zig(root);
					Remove(node[root].rs, val);
				} else {
					zag(root);
					Remove(node[root].ls, val);
				}
				Update(root);
			} else {
				root = 0;
			}
			return ;
		} else {
			node[root].cnt--;
			Update(root);
		}
		return ;
	}
	if (val < node[root].val) Remove(node[root].ls, val);
	else Remove(node[root].rs, val);
	Update(root);
	return ;
}

int GetRank(int root, int val) {
    if (!root) return 0;
    if (node[root].val == val) return node[node[root].ls].siz;
    if (val < node[root].val) return GetRank(node[root].ls, val);
    return GetRank(node[root].rs, val) + node[node[root].ls].siz + node[root].cnt;
}

int GetK(int root, int k) {
	if (k > node[root].siz) return INF;
	if (node[node[root].ls].siz >= k) return GetK(node[root].ls, k);
	if (node[node[root].ls].siz + node[root].cnt >= k) return node[root].val;
	return GetK(node[root].rs, k - node[node[root].ls].siz - node[root].cnt);
}

int GetPre(int val) {
	int ans = 1;
	int p = root;
	while (p) {
		if (node[p].val == val) {
			if (node[p].ls) {
				p = node[p].ls;
				while (node[p].rs) p = node[p].rs;
				ans = p;
			}
			break;
		}
		if (node[p].val < val && node[p].val > node[ans].val) ans = p;
		p = (val < node[p].val ? node[p].ls : node[p].rs);
	}
	return node[ans].val;
}

int GetNxt(int val) {
	int ans = 2;
	int p = root;
	while (p) {
		if (node[p].val == val) {
			if (node[p].rs) {
				p = node[p].rs;
				while (node[p].ls) p = node[p].ls;
				ans = p;
			}
			break;
		}
		if (node[p].val > val && node[p].val < node[ans].val) ans = p;
		p = (val < node[p].val ? node[p].ls : node[p].rs);
	}
	return node[ans].val;
}

int main() {
	freopen("phs.in", "r", stdin);
	freopen("phs.out", "w", stdout);
	Build(root);
	scanf("%d", &n);
	while (n--) {
		int opt, x;
		scanf("%d %d", &opt, &x);
		if (opt == 1) Insert(root, x);
		if (opt == 2) Remove(root, x);
		if (opt == 3) printf("%d\n", GetRank(root, x));
		if (opt == 4) printf("%d\n", GetK(root, x + 1));
		if (opt == 5) printf("%d\n", GetPre(x));
		if (opt == 6) printf("%d\n", GetNxt(x));
	}
	return 0;
}