zoukankan      html  css  js  c++  java
  • 【数据结构】Splay

    struct Splay {
    
        static const int MAXN = 3e6 + 10;
        int top, root, ch[MAXN][2], pa[MAXN];
        int val[MAXN], cnt[MAXN], siz[MAXN];
    
        void _PushUp(int x) {
            siz[x] = siz[ch[x][0]] + siz[ch[x][1]] + cnt[x];
        }
    
        bool _Get(int x) {
            return x == ch[pa[x]][1];
        }
    
        void _Clear(int x) {
            ch[x][0] = 0, ch[x][1] = 0, pa[x] = 0;
            val[x] = 0, siz[x] = 0, cnt[x] = 0;
        }
    
        void _Rotate(int x) {
            int y = pa[x], z = pa[y], d = _Get(x);
            ch[y][d] = ch[x][d ^ 1], pa[ch[x][d ^ 1]] = y;
            ch[x][d ^ 1] = y, pa[y] = x, pa[x] = z;
            if(z)
                ch[z][y == ch[z][1]] = x;
            _PushUp(x), _PushUp(y);
        }
    
        void _Splay(int x) {
            for(int p = pa[x]; p = pa[x]; _Rotate(x)) {
                if(pa[p])
                    _Rotate((_Get(x) == _Get(p)) ? p : x);
            }
            root = x;
        }
    
        int _Prev() {
            int cur = ch[root][0];
            while(ch[cur][1])
                cur = ch[cur][1];
            _Splay(cur);
            return cur;
        }
    
        int _Next() {
            int cur = ch[root][1];
            while(ch[cur][0])
                cur = ch[cur][0];
            _Splay(cur);
            return cur;
        }
    
        void Init() {
            top = 0, root = 0;
        }
    
        void Insert(int v, int c = 1) {
            if(!root) {
                root = ++top;
                val[top] = v, cnt[top] = c;
                _PushUp(top);
                return;
            }
            int cur = root, p = 0;
            while(true) {
                if(val[cur] == v) {
                    cnt[cur] += c;
                    _PushUp(cur), _PushUp(p), _Splay(cur);
                    break;
                }
                p = cur, cur = ch[cur][val[cur] < v];
                if(!cur) {
                    ++top;
                    val[top] = v, cnt[top] = c;
                    pa[top] = p, ch[p][val[p] < v] = top;
                    _PushUp(top), _PushUp(p), _Splay(top);
                    break;
                }
            }
        }
    
        /* "Rank of value v" means the first node with value >= v */
    
        /* Get the rank of value v */
        int GetRank(int v) {
            int cur = root, res = 1;
            while(cur) {
                if(val[cur] > v)
                    cur = ch[cur][0];
                else if(val[cur] == v) {
                    res += siz[ch[cur][0]];
                    _Splay(cur);
                    break;
                } else {
                    res += siz[ch[cur][0]] + cnt[cur];
                    cur = ch[cur][1];
                }
            }
            return res;
        }
    
        /* Get the value with rank r */
        int GetValue(int r) {
            int cur = root, res = INF;
            while(cur) {
                if(siz[ch[cur][0]] >= r)
                    cur = ch[cur][0];
                else if(siz[ch[cur][0]] + cnt[cur] >= r) {
                    res = val[cur];
                    _Splay(cur);
                    break;
                } else {
                    r -= siz[ch[cur][0]] + cnt[cur];
                    cur = ch[cur][1];
                }
            }
            return res;
        }
    
        int GetPrev(int v) {
            Insert(v);
            int res = val[_Prev()];
            Remove(v);
            return res;
        }
    
        int GetNext(int v) {
            Insert(v);
            int res = val[_Next()];
            Remove(v);
            return res;
        }
    
        void Remove(int v, int c = 1) {
            GetRank(v);
            int cur = root;
            if(val[cur] != v)
                return;
            if(cnt[cur] > c)
                cnt[cur] -= c;
            else if(ch[cur][0] && ch[cur][1]) {
                root = _Prev();
                pa[ch[cur][1]] = root;
                ch[root][1] = ch[cur][1];
                _Clear(cur);
            } else {
                root = ch[cur][0] + ch[cur][1];
                pa[root] = 0;
                _Clear(cur);
            }
            _PushUp(root);
            return;
        }
    
    } splay;
    

    耗时大概是Treap的1.5倍。

  • 相关阅读:
    动态规划之解决01背包问题 【转载】
    暴力搜索解0-1背包问题 【转载】
    回溯法之地图着色
    贪心算法之最小生成树
    贪心算法之最短路径
    HMM隐马尔科夫模型
    变分贝叶斯
    Leetcode好的微博
    HMM隐马尔科夫模型浅析
    向量的协方差矩阵浅析
  • 原文地址:https://www.cnblogs.com/purinliang/p/14321732.html
Copyright © 2011-2022 走看看