求助
  • 板块灌水区
  • 楼主pengbonan
  • 当前回复1
  • 已保存回复1
  • 发布时间2024/9/7 19:52
  • 上次更新2024/9/7 22:07:16
查看原帖
求助
1005693
pengbonan楼主2024/9/7 19:52

题目 写的替罪羊树,35pts。
代码:

#include <iostream>
using namespace std;
const int N = 1e6 + 10;
const double alp = 0.75;
struct Node {
	int Ls, rs;
	int val;
	int Tot;
	int size;
	int del;
} tr[N];
int order[N], cnt;
int tr_stack[N], top;
int root = 0;
// 拍扁 
void inor (int u) {
	if (!u)
		return;
	inor(tr[u].Ls);
	if (tr[u].del)
		order[++ cnt] = u;
	else
		tr_stack[++ top] = u;
	inor(tr[u].rs);
}
void InitNode (int u) {
	tr[u].Ls = tr[u].rs = 0;
	tr[u].size = tr[u].Tot = tr[u].del = 1;
}
void update (int u) {
	tr[u].size = tr[tr[u].Ls].size + tr[tr[u].rs].size + 1;
	tr[u].Tot = tr[tr[u].Ls].Tot + tr[tr[u].rs].Tot + 1;
}
// 重建树
void build (int L, int r, int &u) {
	int mid = L + r >> 1;
	u = order[mid];
	if (L == r) {
		InitNode(u);
		return;
	}
	if (L < mid)
		build(1, mid - 1, tr[u].Ls);
	if (L == mid)
		tr[u].Ls = 0;
	build(mid + 1, r, tr[u].rs);
	update(u);
}
void rebuild (int &u) {
	cnt = 0;
	inor(u);
	if (cnt)
		build(1, cnt, u);
	else
		u = 0;
}
bool check (int u) {
	return 1.0 * tr[u].size * alp <= max(1.0 * tr[tr[u].Ls].size, 1.0 * tr[tr[u].rs].size);
//	if (1.0 * tr[u].size * alp <= max(1.0 * tr[tr[u].Ls].size, 1.0 * tr[tr[u].rs].size))
//		return true;
//	else return false;
}
void ins (int &u, int x) {
	if (!u) {
		u = tr_stack[top --];
		tr[u].val = x;
		InitNode(u);
		return;
	}
	tr[u].size ++;
	tr[u].Tot ++;
	if (tr[u].val >= x)
		ins(tr[u].Ls, x);
	else
		ins(tr[u].rs, x);
	if (check(u))
		rebuild(u);
}
int Rank (int u, int x) {
	if (u == 0)
		return 0;
	if (x > tr[u].val)
		return tr[tr[u].Ls].size + tr[u].del + Rank(tr[u].rs, x);
	return Rank(tr[u].Ls, x);
}
int kth (int k) {
	int u = root;
	while (u) {
		if (tr[u].del && tr[tr[u].Ls].size + 1 == k)
			return tr[u].val;
		else if (tr[tr[u].Ls].size >= k)
			u = tr[u].Ls;
		else {
			k -= tr[tr[u].Ls].size + tr[u].del;
			u = tr[u].rs;
		}
	}
	return tr[u].val;
}
void del_rank (int &u, int k) {
	tr[u].size --;
	if (tr[u].del && tr[tr[u].Ls].size + 1 == k) {
		tr[u].del = 0;
		return;
	}
	if (tr[tr[u].Ls].size + tr[u].del >= k)
		del_rank(tr[u].Ls, k);
	else
		del_rank(tr[u].rs, k - tr[tr[u].Ls].size - tr[u].del);
}
void del (int x) {
	del_rank(root, Rank(root, x) + 1);
	if (1.0 * tr[root].Tot * alp >= tr[root].size)
		rebuild(root);
}
signed main () {
	ios::sync_with_stdio(false);
	cin.tie(nullptr), cout.tie(nullptr);
	for (int i = N - 1; i >= 1; i --)
		tr_stack[++ top] = i;
	int q;
	cin >> q;
	while (q --) {
		int op, x;
		cin >> op >> x;
		if (op == 1)
			ins(root, x);
		else if (op == 2)
			del(x);
		else if (op == 3)
			cout << Rank(root, x) + 1 << '\n';
		else if (op == 4)
			cout << kth(x) << '\n';
		else if (op == 5)
			cout << kth(Rank(root, x)) << '\n';
		else if (op == 6)
			cout << kth(Rank(root, x + 1) + 1) << '\n';
	}
	return 0;
} 
2024/9/7 19:52
加载中...