平衡树

【模板】普通平衡树

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;
}
posted @ 2022-12-09 09:49  kroyosh  阅读(38)  评论(0)    收藏  举报