替罪羊树通过计算不平衡率、拍平重建操作,维护树的平衡,实现数据的高效插入、删除
#include <bits/stdc++.h>
#define io cin.tie(0), cout.tie(0), ios::sync_with_stdio(false)
#define LL long long
#define ULL unsigned long long
#define EPS 1e-8
#define INF 0x7fffffff
#define SUB -INF - 1
using namespace std;
const int N = 100010;
const double alpha = 0.75;
struct node
{
int rs, ls;
int val;
int tot;
int size;
int del;
} t[N];
int order[N], cnt;
int tree_stack[N], top = 0;
int root = 0;
void inorder(int u)
{
if (!u)
return;
inorder(t[u].ls);
if (t[u].del)
order[++cnt] = u;
else
tree_stack[++top] = u;
inorder(t[u].rs);
}
void Initnode(int u)
{
t[u].ls = t[u].rs = 0;
t[u].size = t[u].tot = t[u].del = 1;
}
void update(int u)
{
t[u].size = t[t[u].ls].size + t[t[u].rs].size + 1;
t[u].tot = t[t[u].ls].tot + t[t[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(l, mid - 1, t[u].ls);
if (l == mid)
t[u].ls = 0;
build(mid + 1, r, t[u].rs);
update(u);
}
void rebuild(int &u)
{
cnt = 0;
inorder(u);
if (cnt)
build(1, cnt, u);
else
u = 0;
}
bool notbalance(int u)
{
if ((double)t[u].size * alpha <= (double)max(t[t[u].ls].size, t[t[u].rs].size))
return true;
return false;
}
void Insert(int &u, int x)
{
if (!u)
{
u = tree_stack[top--];
t[u].val = x;
Initnode(u);
return;
}
t[u].size++;
t[u].tot++;
if (t[u].val >= x)
Insert(t[u].ls, x);
else
Insert(t[u].rs, x);
if (notbalance(u))
rebuild(u);
}
int Rank(int u, int x)
{
if (u == 0)
return 0;
if (x > t[u].val)
return t[t[u].ls].size + t[u].del + Rank(t[u].rs, x);
return Rank(t[u].ls, x);
}
int kth(int k)
{
int u = root;
while (u)
{
if (t[u].del && t[t[u].ls].size + 1 == k)
return t[u].val;
else if (t[t[u].ls].size >= k)
u = t[u].ls;
else
{
k -= t[t[u].ls].size + t[u].del;
u = t[u].rs;
}
}
return t[u].val;
}
void Del_k(int &u, int k)
{
t[u].size--;
if (t[u].del && t[t[u].ls].size + 1 == k)
{
t[u].del = 0;
return;
}
if (t[t[u].ls].size + t[u].del >= k)
Del_k(t[u].ls, k);
else
Del_k(t[u].rs, k - t[t[u].ls].size - t[u].del);
}
void Del(int x)
{
Del_k(root, Rank(root, x) + 1);
if (t[root].tot * alpha >= t[root].size)
rebuild(root);
}
int main()
{
for (int i = N - 1; i >= 1; i--)
tree_stack[++top] = i;
int q;
cin >> q;
while (q--)
{
int opt, x;
cin >> opt >> x;
switch (opt)
{
case 1:
Insert(root, x);
break;
case 2:
Del(x);
break;
case 3:
printf("%d\n", Rank(root, x) + 1);
break;
case 4:
printf("%d\n", kth(x));
break;
case 5:
printf("%d\n", kth(Rank(root, x)));
break;
case 6:
printf("%d\n", kth(Rank(root, x + 1) + 1));
break;
}
}
return 0;
}