zoukankan      html  css  js  c++  java
  • 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;
    
  • 相关阅读:
    【WCF】授权策略详解
    【WCF】基址与默认终结点
    【Win 10 应用开发】手写识别
    【.net 深呼吸】连接Access数据库应注意的几点
    【WCF】自定义地址头的筛选器
    【Win 10 应用开发】InkToolBar——涂鸦如此简单
    【WCF】为终结点地址应用地址头
    【.net 深呼吸】EqualityComparer——自定义相等比较
    【.net 深呼吸】使用二进制格式来压缩XML文档
    PHP根据传入的经纬度,和距离范围,返回所有在距离范围内的经纬度的取值范围
  • 原文地址:https://www.cnblogs.com/Chain-Forward-Star/p/15047428.html
Copyright © 2011-2022 走看看