44分求助,写Splay的萌新看蒙了
查看原帖
44分求助,写Splay的萌新看蒙了
146852
RocksonLee楼主2021/11/18 11:47

RT

#include <bits/stdc++.h>
using namespace std;

#define il inline
#define Maxn 500100
#define cl(a, b) memset(a, b, sizeof(a))
typedef long long ll;
typedef unsigned long long ull;

#define In(a) a = Read()
il int Read()
{
    int v = 1, x = 0;
    char ch = getchar();
    while (ch > '9' || ch < '0')
    {
        if (ch == '-') v = -1;
        ch = getchar();
    }
    while (ch >= '0' && ch <= '9')
    {
        x = (x << 3) + (x << 1) + ch - '0';
        ch = getchar();
    }
    return v * x;
}

il void Out(int x)
{
    if (x < 0) x = -x, putchar('-');
    if (x > 9) Out(x / 10);
    putchar(x % 10 + '0');
}

int Cnt[Maxn], Son[Maxn][2], Fa[Maxn], Size[Maxn], Val[Maxn];

int N, Root = 0, Tot = 0;

#define Gson(x) (Son[Fa[x]][1] == x)

il void Push_up(int x)
{
    Size[x] = Size[Son[x][0]] + Size[Son[x][1]] + Cnt[x];
}

il void Rotote(int x)
{
    int y = Fa[x], z = Fa[y], k = Gson(x), temp = Son[x][k ^ 1];
    Son[z][Gson(y)] = x, Fa[x] = z;
    Son[y][k] = temp;
    Fa[temp] = y;
    Son[x][k ^ 1] = y;
    Fa[y] = x;
    Push_up(y);
    Push_up(x);
}

il void Splay(int x, int goal)
{
    while (Fa[x] != goal) // x->goal.son
    {
        int y = Fa[x], z = Fa[y];
        if (z != goal) Gson(x) ^ Gson(y) ? Rotote(x) : Rotote(y);
        Rotote(x);
    }
    if (goal == 0) Root = x;
}

il void Insert(int x)
{
    int now = Root, ff = 0;
    while (now && Val[now] != x) ff = now, now = Son[now][x > Val[now]];
    if (now)
        Cnt[now]++;
    else
    {
        now = ++Tot;
        if (ff) Son[ff][x > Val[ff]] = now;
        Son[now][0] = Son[now][1] = 0;
        Fa[now] = ff, Val[now] = x;
        Cnt[now] = Size[now] = 1;
    }
    Splay(now, 0);
}

il void Find(int x) // find val->x
{
    int now = Root;
    if (!now) return;
    while (Son[now][x > Val[now]] && x != Val[now]) now = Son[now][x > Val[now]];
    Splay(now, 0);
}

il int Next(int x, int f)
{
    Find(x);
    int now = Root;
    if ((Val[now] > x && f) || (Val[now] < x && !f)) return now;
    now = Son[now][f];
    while (Son[now][f ^ 1]) now = Son[now][f ^ 1];
    return now;
}

il void Del(int x)
{
    int last = Next(x, 0), next = Next(x, 1);
    Splay(last, 0), Splay(next, last);
    int del = Son[next][0];
    if (Cnt[del] > 1)
        Cnt[del]--, Splay(del, 0);
    else
        Son[next][0] = 0;
}

il int Findth(int x)
{
    int now = Root;
    if (Size[now] < x) return 0;
    while (1)
    {
        int left = Son[now][0];
        if (x > Size[left] + Cnt[now])
            x -= Size[left] + Cnt[now], now = Son[now][1];
        else if (Size[left] >= x)
            now = left;
        else
            return Val[now];
    }
}

int main()
{
    freopen("P3369_3.in", "r", stdin);
    int n;
    In(n);
    for (int i = 0, temp, x; i < n; i++)
    {
        In(temp), In(x);
        if (temp == 1) Insert(x);
        if (temp == 2) Del(x);
        if (temp == 3) Find(x), Out(Size[Son[Root][0]] + 1), printf("\n");
        if (temp == 4) Out(Findth(x)), printf("\n");
        if (temp == 5) Out(Val[Next(x, 0)]), printf("\n");
        if (temp == 6) Out(Val[Next(x, 1)]), printf("\n");
    }
    return 0;
}
2021/11/18 11:47
加载中...