【模板】普通平衡树
FHQ treap
code
const int N = 1e5 + 10;
int n;
int root, idx;
struct FHQ
{
int l, r, siz, key, val;
}tr[N];
int nwid(int x)
{
idx ++ ;
tr[idx].siz = 1;
tr[idx].val = x;
tr[idx].key = rand();
return idx;
}
void update(int x)
{
tr[x].siz = tr[tr[x].l].siz + tr[tr[x].r].siz + 1;
}
void split(int now, int val, int &x, int &y)//分裂
{
if (!now)
{
x = y = 0;
return ;
}
if (tr[now].val <= val)
{
x = now;
split(tr[now].r, val, tr[now].r, y);
}
else
{
y = now;
split(tr[now].l, val, x, tr[now].l);
}
update(now);
}
int merge(int x, int y)//合并
{
if (!x || !y) return x + y;
if (tr[x].key > tr[y].key)
{
tr[x].r = merge(tr[x].r, y);
update(x);
return x;
}
else
{
tr[y].l = merge(x, tr[y].l);
update(y);
return y;
}
}
void insert(int val)//插入
{
int x, y;
split(root, val, x, y);
root = merge(merge(x, nwid(val)), y);
}
void delet(int val)//删除
{
int x, y, z;
split(root, val, x, z);
split(x, val - 1, x, y);
y = merge(tr[y].l, tr[y].r);
root = merge(merge(x, y), z);
}
void rank_of_val(int val)//按值找排名
{
int x, y;
split(root, val - 1, x, y);
wrn(tr[x].siz + 1);
root = merge(x, y);
}
void kth(int k)//找排名为k的数
{
int now = root;
while (now)
{
if (tr[tr[now].l].siz + 1 == k) break;
if (tr[tr[now].l].siz >= k) now = tr[now].l;
else
{
k -= tr[tr[now].l].siz + 1;
now = tr[now].r;
}
}
wrn(tr[now].val);
}
void pre(int val)//前驱
{
int x, y;
split(root, val - 1, x, y);
int now = x;
while (tr[now].r) now = tr[now].r;
wrn(tr[now].val);
root = merge(x, y);
}
void nxt(int val)//后继
{
int x, y;
split(root, val, x, y);
int now = y;
while (tr[now].l) now = tr[now].l;
wrn(tr[now].val);
root = merge(x, y);
}
int main()
{
rd(n);
while (n -- )
{
int op, x;
rd(op, x);
if (op == 1)
insert(x);
else if (op == 2)
delet(x);
else if (op == 3)
rank_of_val(x);
else if (op == 4)
kth(x);
else if (op == 5)
pre(x);
else
nxt(x);
}
return 0;
}