替罪羊树#8-12WA #14TLE
查看原帖
替罪羊树#8-12WA #14TLE
226686
Herobrine6265楼主2023/11/12 19:19

rt

WA的点根据提示是在某不知名操作上给出的都是0

TLE未知

#include <vector>
#include <iostream>
using namespace std;
struct node
{
    int val;
    int l = 0, r = 0;
    int size = 1, fact = 1;
    int cnt = 1;
} p[100005];
int n, root = 1, cnt = 1;
inline bool imbalance(int now)
{
    if (0.7 * p[now].size >= p[now].fact)
        return true;
    if (max(p[p[now].l].size, p[p[now].r].size) >= 0.75 * p[now].size)
        return true;
    return false;
}
vector<int> v;
void ldr(int now)
{
    if (!now)
        return;
    ldr(p[now].l);
    if (p[now].cnt)
        v.push_back(now);
    ldr(p[now].r);
}
void lift(int l, int r, int &now)
{
    if (l == r)
    {
        now = v[l];
        p[now].size = p[now].fact = p[now].cnt;
        p[now].l = p[now].r = 0;
        return;
    }
    int mid = (r - l) / 2 + l;
    /*while (mid > l && p[v[mid - 1]].val == p[v[mid]].val)
        mid--;*/
    now = v[mid];
    if (l < mid)
        lift(l, mid - 1, p[now].l);
    else
        p[now].l = 0;
    lift(mid + 1, r, p[now].r);
    p[now].size = p[p[now].l].size + p[p[now].r].size + p[now].cnt;
    p[now].fact = p[p[now].l].fact + p[p[now].r].fact + p[now].cnt;
}
void rebuild(int &now)
{
    v.clear();
    ldr(now);
    if (v.empty())
        now = 0;
    else
        lift(0, v.size() - 1, now);
}
void update(int now, int end)
{
    if (!now)
        return;
    if (p[now].val > p[end].val)
        update(p[now].l, end);
    else
        update(p[now].r, end);
    p[now].size = p[p[now].l].size + p[p[now].r].size + p[now].cnt;
    p[now].fact = p[p[now].l].fact + p[p[now].r].fact + p[now].cnt;
}
void check(int &now, int end)
{
    if (now == end)
        return;
    if (imbalance(now))
    {
        rebuild(now);
        update(root, now);
        return;
    }
    if (p[now].val < p[end].val)
        check(p[now].l, end);
    else
        check(p[now].r, end);
}
void insert(int &now, int inum)
{
    if (!now)
    {
        now = cnt++;
        p[now].val = inum;
        check(root, now);
        return;
    }
    p[now].size++;
    p[now].fact++;
    if (inum < p[now].val)
        insert(p[now].l, inum);
    else if (inum == p[now].val)
    {
        p[now].cnt++;
        check(root, now);
    }
    else
        insert(p[now].r, inum);
}
void del(int now, int dnum)
{
    p[now].fact--;
    if (p[now].val == dnum && p[now].cnt)
    {
        p[now].cnt--;
        check(root, now);
        return;
    }
    if (dnum < p[now].val)
        del(p[now].l, dnum);
    else
        del(p[now].r, dnum);
}
int getrank(int num)
{
    int rank = 1, now = root;
    while (now)
    {
        if (p[now].val < num)
        {
            rank += p[now].cnt + p[p[now].l].fact;
            now = p[now].r;
        }
        else
            now = p[now].l;
    }
    return rank;
}
int getnum(int rank)
{
    int now = root;
    while (now)
    {
        if (p[now].cnt && p[p[now].l].fact + p[now].cnt == rank)
            break;
        if (p[p[now].l].fact < rank)
        {
            rank -= p[p[now].l].fact + p[now].cnt;
            now = p[now].r;
        }
        else
            now = p[now].l;
    }
    return p[now].val;
}
int main()
{
    p[0].fact = p[0].size = p[0].cnt = 0;
    ios::sync_with_stdio(false);
#ifndef ONLINE_JUDGE
    freopen("out.out", "w", stdout);
#endif
    cin >> n;
    for (int i = 1; i <= n; i++)
    {
        int opt, x;
        cin >> opt >> x;
        if (opt == 1)
        {
            if (cnt == 1 || root == 0)
            {
                root = cnt++;
                p[root].val = x;
            }
            else
                insert(root, x);
        }
        else if (opt == 2)
            del(root, x);
        else if (opt == 3)
            cout << getrank(x) << endl;
        else if (opt == 4)
            cout << getnum(x) << endl;
        else if (opt == 5)
            cout << getnum(getrank(x) - 1) << endl;
        else if (opt == 6)
            cout << getnum(getrank(x + 1)) << endl;
    }
    return 0;
}
2023/11/12 19:19
加载中...