Splay

#include <cstdio>
#define ls t[rt].c[0]
#define rs t[rt].c[1]

const int N = 1e5 + 5;

int read(int x = 0, int f = 1, char c = getchar()) {
    for (; c < '0' || c > '9'; c = getchar())
        if (c == '-') f = -1;
    for (; c >='0' && c <='9'; c = getchar())
        x = x * 10 + c - '0';
    return x * f;
}

int trc, root;

struct Tree {
    int x, s, sz, f, c[2];
}t[N];

int Find(int x, int rt = root) {
    for (; x != t[rt].x && t[rt].c[x > t[rt].x]; rt = t[rt].c[x > t[rt].x]);
    return rt;
}

int Get(int x) { 
    return t[t[x].f].c[1] == x; 
}

void Link(int x, int f, int s) { 
    t[x].f = f; t[f].c[s] = x; 
}

void Up(int rt) { 
    t[rt].sz = t[rt].s + t[ls].sz + t[rs].sz; 
}

void Rotate(int x) {
    int y = t[x].f, z = t[y].f, s = Get(x), s2 = Get(y);
    Link(t[x].c[s^1], y, s); Link(y, x, s ^ 1); Link(x, z, s2);
    Up(y); Up(x);
}

void Splay(int x, int to = 0) {
    while (t[x].f != to) {
        int y = t[x].f, z = t[y].f;
        if (z != to) Get(x) == Get(y) ? Rotate(y) : Rotate(x);
        Rotate(x);
    }
    if (!to) root = x;
}

void Insert(int x) {
    int rt = Find(x);
    if (t[rt].x == x) return t[rt].s++, Splay(rt);
    t[++trc] = (Tree) {x, 1, 1, rt};
    if (rt) t[rt].c[x > t[rt].x] = trc;
    Splay(trc);
}

int Next(int x, int k) {
    int rt = root;
    if ((!k && t[rt].x < x) || (k && t[rt].x > x)) return rt;
    for (rt = t[rt].c[k]; t[rt].c[k^1]; rt = t[rt].c[k^1]);
    return rt;
}

void Del(int x) {
    int rt = Find(x);
    if (t[rt].x != x) return;
    Splay(rt);
    if (t[rt].s > 1) return t[rt].s--, void();
    int l = Next(x, 0), r = Next(x, 1);
    Splay(l, 0); Splay(r, root);
    t[t[rt].f].c[Get(rt)] = 0;
}

int Kth(int k) {
    int rt = root;
    while (1) {
        if (t[ls].sz >= k) rt = ls;
        else if (t[rt].s >= (k -= t[ls].sz)) return rt;
        else k -= t[rt].s, rt = rs;
    }
}

int main() {
    int m = read();
    Insert(1e9); Insert(-1e9);
    while (m--) {
        int od = read(), x = read(), rt;
        if (od == 1) Insert(x);
        else if (od == 2) Del(x);
        else if (od == 3) Splay(Find(x)), printf("%d
", t[t[root].c[0]].sz);
        else if (od == 4) Splay(rt = Kth(x + 1)), printf("%d
", t[rt].x);
        else if (od == 5) Splay(Find(x)), printf("%d
", t[Next(x, 0)].x);
        else if (od == 6) Splay(Find(x)), printf("%d
", t[Next(x, 1)].x);
    }
    return 0;
}
原文地址:https://www.cnblogs.com/shawk/p/14158042.html