splay模板(封装)

· · 个人记录

#pragma GCC optimize(2)
#include <iostream>

using namespace std;

const int N = 1e5 + 10;

class Splay_Tree
{
    #define fa(x) tr[x].fa
    #define ls(x) tr[x].ch[0]
    #define rs(x) tr[x].ch[1]
    #define root tr[0].ch[1]
    public:
        int idx;
        struct Splay
        {
            int ch[2];
            int fa, cnt, val, size;
        }tr[N];

        int ident(int x) {return tr[fa(x)].ch[1] == x;}

        void update(int x) {tr[x].size = tr[ls(x)].size + tr[rs(x)].size + tr[x].cnt;}

        int set_node(int v, int f)
        {
            this->idx ++ ;
            tr[this->idx].val = v; tr[this->idx].fa = f;
            tr[this->idx].cnt = tr[this->idx].size = 1;
            return this->idx;
        }

        void connect(int x, int y, int how)
        {
            tr[y].ch[how] = x;
            tr[x].fa = y;
        }

        void rotate(int x)
        {
            int Y = tr[x].fa, R = tr[Y].fa;
            int Yson = ident(x), Rson = ident(Y);
            connect(tr[x].ch[Yson ^ 1], Y, Yson);
            connect(Y, x, Yson ^ 1);
            connect(x, R, Rson);
            update(Y);
            update(x);
        }

        void splay(int x, int to)
        {
            to = tr[to].fa;
            while (fa(x) ^ to)
            {
                int y = fa(x);
                if (fa(y) == to)
                    rotate(x);
                else if (ident(x) == ident(y))
                    rotate(y), rotate(x);
                else 
                    rotate(x), rotate(x);
            }
        }

        void insert(int x)
        {
            int now = root;
            if (!now) 
                root = set_node(x, 0);
            else
            {
                while (1)
                {
                    tr[now].size ++ ;
                    if (tr[now].val == x)
                    {
                        tr[now].cnt ++ ;
                        splay(now, root);
                        return ;
                    }
                    int nxt = x >= tr[now].val;
                    if (!tr[now].ch[nxt])
                    {
                        int p = set_node(x, now);
                        tr[now].ch[nxt] = p;
                        splay(p, root);
                        return ;
                    }
                    now = tr[now].ch[nxt];
                }
            }
        }

        int find(int x)
        {
            int now = root;
            while (1)
            {
                if (!now) return 0;
                if (tr[now].val == x)
                {
                    splay(now, root);
                    return now;
                }
                int nxt = x >= tr[now].val;
                now = tr[now].ch[nxt];
            }
        }

        void delet(int x)
        {
            int pos = find(x);
            if (!pos) return ;
            if (tr[pos].cnt > 1)
            {
                tr[pos].cnt -- ; tr[pos].size -- ;
                return ;
            }
            else
            {
                if (!tr[pos].ch[0] && !tr[pos].ch[1])
                {
                    root = 0;
                    return ;
                }
                else if (!tr[pos].ch[0])
                {
                    root = tr[pos].ch[1];
                    tr[root].fa = 0;
                    return ;
                }
                else
                {
                    int left = tr[pos].ch[0];
                    while (rs(left)) left = rs(left);
                    splay(left, tr[pos].ch[0]);
                    connect(tr[pos].ch[1], left, 1);
                    connect(left, 0, 1);
                    update(left);
                }
            }
        }

        int rank(int x)
        {
            return tr[ls(find(x))].size + 1;
        }

        int value(int x)
        {
            int now = root;
            while (1)
            {
                int tem_num = tr[now].size - tr[rs(now)].size;
                if (tr[ls(now)].size < x && x <= tem_num)
                {
                    splay(now, root);
                    return tr[now].val;
                }
                if (x < tem_num) now = ls(now);
                else now = rs(now), x -= tem_num;
            }
        }

        int prev(int x)
        {
            int now = root, ans = -0x3f3f3f3f;
            while (now)
            {
                if (tr[now].val < x)
                    ans = max(ans, tr[now].val);
                int nxt = x <= tr[now].val ? 0 : 1;
                now = tr[now].ch[nxt];
            }
            return ans;
        }

        int nxt(int x)
        {
            int now = root, ans = 0x3f3f3f3f;
            while (now)
            {
                if (tr[now].val > x)
                    ans = min(ans, tr[now].val);
                int nxt = x < tr[now].val ? 0 : 1;
                now = tr[now].ch[nxt];
            }
            return ans;
        }

}tree;

int n;
int main(void)
{
    scanf("%d", &n);
    while (n -- )
    {
        int opt, x;
        scanf("%d%d", &opt, &x);
        if (opt == 1) tree.insert(x);
        else if (opt == 2) tree.delet(x);
        else if (opt == 3) printf("%d\n", tree.rank(x)); 
        else if (opt == 4) printf("%d\n", tree.value(x));
        else if (opt == 5) printf("%d\n", tree.prev(x));
        else printf("%d\n", tree.nxt(x));
    }
    return 0;
}