社区讨论

FHQ Treap 样例未过求调QWQ

P3369【模板】普通平衡树参与者 4已保存回复 3

讨论操作

快速查看讨论及其快照的属性,并进行相关操作。

当前回复
3 条
当前快照
1 份
快照标识符
@mia0ilzx
此快照首次捕获于
2025/11/22 16:13
4 个月前
此快照最后确认于
2025/11/22 16:51
4 个月前
查看原帖
小萌新第一次学FHQ Treap qwqwq
CPP
#include<bits/stdc++.h>
using namespace std;
const int QWQ = 1e6 + 10;
int cnt, root, n;
struct node
{
    int ls, rs, key, rnd, size;
}tr[QWQ];
void newNode(int x)
{
    tr[++ cnt].size = 1;
    tr[cnt].ls = tr[cnt].rs = 0;
    tr[cnt].key = 0;
    tr[cnt].rnd = rand();
}
void update(int u)
{
    int ls = tr[u].ls, rs = tr[u].rs;
    tr[u].size = tr[ls].size + tr[rs].size + 1;
}
void split(int u, int x, int &L, int &R)
{
    if(u == 0)
    {
        L = R = 0;
        return ;
    }
    if(tr[u].key <= x)
    {
        L = u;
        split(tr[u].rs, x, tr[u].rs, R);
    }
    else
    {
        R = u;
        split(tr[u].ls, x, L, tr[u].ls);
    }
    update(u);
}
int merge(int L, int R)
{
    if(L == 0 || R == 0)
    {
        return L + R;
    }
    if(tr[L].rnd > tr[R].rnd)
    {
        tr[L].rs = merge(tr[L].rs, R);
        update(L);
        return L;
    }
    else{
        tr[R].ls = merge(L, tr[R].ls);
        update(R);
        return R;
    }
}
void Insert(int x)
{
    int L, R;
    split(root, x, L, R);
    newNode(x);
    int qwq = merge(L, cnt);
    root = merge(qwq, R);
}
void del(int x)
{
    int L, R, p;
    split(root, x, L, R);
    split(L, x - 1, L, p);
    p = merge(tr[p].ls, tr[p].rs);
    root = merge(merge(L, p), R);
}
int rankk(int x)
{
    int L, R;
    split(root, x - 1, L, R);
    int ans = tr[L].size + 1;
    root = merge(L, R);
    return ans;
}
int kth (int u, int k)
{
    if (k == tr[tr[u].ls].size + 1)
    {
        return u;
    }
    if (k <= tr[tr[u].ls].size)
    {
        return kth(tr[u].ls, k);
    }
    if (k > tr[tr[u].ls].size)
    {
        return kth(tr[u].rs, k - tr[tr[u].ls].size - 1);
    }
    return 114514;
}
void Successor(int x)
{
    int L, R;
    split(root, x, L, R);
    cout << tr[kth(R, 1)].key << endl;
    root = merge(L, R);
}
void Precursor(int x)
{
    int L, R;
    split(root, x - 1, L, R);
    cout << tr[kth(R, 1)].key << endl;
    root = merge(L, R);
}
signed main()
{
    srand(time(NULL));
    cin >> n;
    while(n --)
    {
        int op, x;
        cin >> op >> x;
        if(op == 1)
        {
            Insert(x);
        }
        if(op == 2)
        {
            del(x);
        }
        if(op == 3)
        {
            cout << rankk(x) << endl;
        }
        if(op == 4)
        {
            cout << tr[kth(root, x)].key << endl;
        }
        if(op == 5)
        {
            Precursor(x);
        }
        if(op == 6)
        {
            Successor(x);
        }
    }
}

回复

3 条回复,欢迎继续交流。

正在加载回复...