Note -「模板」Splay

// Splay

const int MAXN = 1e5 + 5;

struct Splay_Tree {
#define INF 0x3f3f3f3f
    struct Splay_Node {
        int son[2], val, cnt, size, fa;
#define lson tr[p].son[0]
#define rson tr[p].son[1]
        Splay_Node() {}
        Splay_Node(int Val, int Cnt, int Size, int Fa) {
            val = Val;
            cnt = Cnt;
            size = Size;
            fa = Fa;
        }
    } tr[MAXN];

    int tot, root;

    bool Ident(int p) { return tr[tr[p].fa].son[1] == p; }

    int Get(int val, int fa) {
        tr[++tot].fa = fa, tr[tot].cnt = tr[tot].size = 1, tr[tot].val = val;
        return tot;
    }

    void Update(int p) { tr[p].size = tr[lson].size + tr[rson].size + tr[p].cnt; }

    void Build() {
        root = Get(-INF, 0);
        tr[root].son[1] = Get(INF, root);
        Update(root);
    }

    void Connect(int p, int fa, int flag) { tr[fa].son[flag] = p, tr[p].fa = fa; }

    void Rotate(int p) {
        int fa = tr[p].fa, grand = tr[fa].fa;
        int flag1 = Ident(p), flag2 = Ident(fa);
        Connect(p, grand, flag2);
        Connect(tr[p].son[flag1 ^ 1], fa, flag1);
        Connect(fa, p, flag1 ^ 1);
        Update(fa);
        Update(p);
    }

    void Splay(int p, int to) {
        for (int fa = tr[p].fa; tr[p].fa != to; Rotate(p), fa = tr[p].fa)
            if (tr[fa].fa != to)
                Ident(p) == Ident(fa) ? Rotate(fa) : Rotate(p);
        if (!to)
            root = p;
    }

    int Find(int p, int val) {
        if (!p)
            return 0;
        if (val == tr[p].val)
            return p;
        else if (val < tr[p].val)
            return Find(lson, val);
        return Find(rson, val);
    }

    void Insert(int &p, int val, int fa) {
        if (!p)
            Splay(p = Get(val, fa), 0);
        else if (val == tr[p].val) {
            ++tr[p].cnt;
            Splay(p, 0);
        } else if (val < tr[p].val)
            Insert(lson, val, p);
        else
            Insert(rson, val, p);
    }

    void Delete(int val) {
        int p = Find(root, val);
        if (!p)
            return;
        if (tr[p].cnt > 1) {
            --tr[p].cnt;
            Splay(p, 0);
            Update(p);
            return;
        }
        Splay(p, 0);
        int l = lson, r = rson;
        while (tr[l].son[1]) l = tr[l].son[1];
        while (tr[r].son[0]) r = tr[r].son[0];
        Splay(l, 0);
        Splay(r, l);
        tr[r].son[0] = 0;
        Update(r);
        Update(l);
    }

    int Get_Rank(int p, int val) {
        if (!p)
            return 0;
        if (val == tr[p].val) {
            int res = tr[lson].size + 1;
            Splay(p, 0);
            return res;
        } else if (val < tr[p].val)
            return Get_Rank(lson, val);
        int res = tr[lson].size + tr[p].cnt;
        return Get_Rank(rson, val) + res;
    }

    int Get_Val(int p, int rank) {
        if (!p)
            return INF;
        if (tr[lson].size >= rank)
            return Get_Val(lson, rank);
        else if (tr[lson].size + tr[p].cnt >= rank) {
            Splay(p, 0);
            return tr[p].val;
        }
        return Get_Val(rson, rank - tr[lson].size - tr[p].cnt);
    }

    int Get_Pre(int val) {
        int p = root, ret;
        while (p) {
            if (tr[p].val < val) {
                ret = tr[p].val;
                p = rson;
            } else
                p = lson;
        }
        Splay(root, 0);
        return ret;
    }

    int Get_Next(int val) {
        int p = root, ret;
        while (p) {
            if (tr[p].val > val) {
                ret = tr[p].val;
                p = lson;
            } else
                p = rson;
        }
        Splay(root, 0);
        return ret;
    }
#undef lson
#undef rson
} tree;
原文地址:https://www.cnblogs.com/Chain-Forward-Star/p/15047428.html