• Splay模板


    并没有写序列翻转的板子;

    【模板】普通平衡树(Treap/SBT)

    #include <iostream>
    #include <cstdio> 
    #include <cstring>
    using namespace std;
    #define maxn 10000010
    #define inf 0x7f7f7f7f
    
    
    struct SplayTree
    {
        int ch[2], fa;
        int val, siz;
        int cnt;// 副本数 
    }t[maxn];
    
    int Root, tot;
    
    void pushup(int o)
    {
        t[o].siz = t[t[o].ch[0]].siz + t[t[o].ch[1]].siz + t[o].cnt;
    }
    
    void rotate(int x)
    {
        int y = t[x].fa, d = (t[y].ch[1] == x);
        t[ t[y].ch[d] = t[x].ch[d ^ 1] ].fa = y; // x 的儿子给 y ;   
        t[ t[x].fa = t[y].fa ].ch[ t[t[y].fa].ch[1] == y ] = x; // x 归为 y 的父亲的儿子 ; 
        t[ t[x].ch[d ^ 1] = y ].fa = x; // y 归为 x 的儿子; 
        pushup(y), pushup(x);
    }
    
    void Splay(int x, int f) // 把 x 旋转成 f 的儿子, 如果 f = 0, x 旋转到根节点: 
    {
        while(t[x].fa != f)
        {
            int y = t[x].fa, z = t[y].fa;
            if(z != f)
            {
            /*    if ((t[z].ch[0] == y) == (t[y].ch[0] == x)) {
                rotate(y);
                } else {
                    rotate(x);
                }*/
                rotate( (t[z].ch[0] == y) == (t[y].ch[0] == x) ? y : x);// x 与 y 为同一边子树 旋转 y, 否则旋转 x; 
            }
            rotate(x);
        }
        pushup(x);
        if(f == 0) Root = x;
    }
    
    void insert(int v)
    {
        int o = Root, u = 0;
        while(o && t[o].val != v)
        {
            u = o;
            int d = t[o].val < v;
            o = t[o].ch[d];
        }
        if(o)
        {
            t[o].cnt ++;
            pushup(o);
        }
        else
        {
            o = ++tot;
            if (u) 
            {
                int d = t[u].val < v;
                t[u].ch[d] = o;
            }
            t[o].fa = u;
            t[o].val = v;//cout<<t[o].val<<endl;
            t[o].siz = 1;
            t[o].cnt = 1;
            t[o].ch[1] = t[o].ch[0] = 0;
        }
        Splay(o, 0);
    }
    
    int K_th(int k)
    {
        int o = Root;
        if(t[o].siz < k)
        {
            return 0;
        }
        while(1)
        {
            if(k > t[t[o].ch[0]].siz + t[o].cnt)
            {
                k -= t[t[o].ch[0]].siz + t[o].cnt;
                o = t[o].ch[1];
            }
            else
            
                if(t[t[o].ch[0]].siz >= k)
                {
                    o = t[o].ch[0];
                }
                else
                {
                    break;
                }
            
        }
        Splay(o, 0);
        return t[o].val;
            
    }
    
    void Find(int x)
    {
        int o = Root;
        if(!o) return ;
    /*    while(1)
        {
            if(t[o].val == x)
            {
                Splay(o, 0);
                return ;
            }
            int d = t[o].val < x;
            if(!t[o].ch[o]) return ;
            o = t[o].ch[o];
        }*/
        while(t[o].ch[t[o].val < x] and x != t[o].val)
        {
            o = t[o].ch[t[o].val < x];
        }
        Splay(o, 0);
    }
    
    int Next(int x, int d)
    {
        Find(x);
        int o = Root;
        if( (t[o].val > x and d) or (t[o].val < x and !d)) return o;
        o = t[o].ch[d];
        while(t[o].ch[d ^ 1]) o = t[o].ch[d ^ 1];
        return o;
    }
    
    void Del(int x)
    {
        int lst = Next(x, 0);
        int nxt = Next(x, 1);
        Splay(lst, 0);Splay(nxt, lst);
        int del = t[nxt].ch[0];
        if(t[del].cnt > 1) 
        {
            t[del].cnt --;
            Splay(del, 0);
        }
        else t[nxt].ch[0] = 0;
    }
    
    int main()
    {
        insert(inf);
        insert(-inf);
        int n;
        cin >> n;
        while(n--)
        {
            int opt, x;
            scanf("%d%d", &opt, &x);
            if(opt == 1)
            {
                insert(x);
            }
            else if(opt == 2)
            {
                Del(x);
            }
            else if(opt == 3)
            {
                Find(x);
                printf("%d
    ", t[t[Root].ch[0]].siz);
            }
            else if(opt == 4)
            {
                printf("%d
    ", K_th(x + 1));
            }
            else if(opt == 5)
            {
                printf("%d
    ", t[Next(x, 0)].val);
            }
            else
            {
                printf("%d
    ", t[Next(x, 1)].val);
            }
        }
        return 0;    
    }
    
    zZhBr
  • 相关阅读:
    #JavaScript 闭包问题详解 #打倒心魔
    Typora + cnblog 图片自动上传 (超详细哦)
    #FUNCTION#CALL对象中的函数内作用域问题.md
    #windows #Github #HOST
    #######对象迭代器######
    #为什么不建议使用for...in 去遍历数组
    #前后端附件传输,去重的一种方式#解决方案
    #页面滚动刷新的实现原理 #下拉刷新#上拉刷新#drag to fresh
    自己动手实现一个阻塞队列
    APC注入
  • 原文地址:https://www.cnblogs.com/BriMon/p/8974945.html
Copyright © 2020-2023  润新知