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


    题目描述

    您需要写一种数据结构(可参考题目标题),来维护一些数,其中需要提供以下操作:

    1. 插入x数

    2. 删除x数(若有多个相同的数,因只删除一个)

    3. 查询x数的排名(排名定义为比当前数小的数的个数+1。若有多个相同的数,因输出最小的排名)

    4. 查询排名为x的数

    5. 求x的前驱(前驱定义为小于x,且最大的数)

    6. 求x的后继(后继定义为大于x,且最小的数)

    输入输出格式

    输入格式:

    第一行为n,表示操作的个数,下面n行每行有两个数opt和x,opt表示操作的序号( 1 leq opt leq 61opt6 )

    输出格式:

    对于操作3,4,5,6每行输出一个数,表示对应答案

    输入输出样例

    输入样例#1: 复制
    10
    1 106465
    4 1
    1 317721
    1 460929
    1 644985
    1 84185
    1 89851
    6 81968
    1 492737
    5 493598
    输出样例#1: 复制
    106465
    84185
    492737

    说明

    时空限制:1000ms,128M

    1.n的数据范围: n leq 100000n100000

    2.每个数的数据范围: [-{10}^7, {10}^7][107,107]

    来源:Tyvj1728 原名:普通平衡树

    在此鸣谢

    #include<iostream>
    #include<cstdio>
    #include<cmath>
    #include<algorithm>
    using namespace std;
    
    const int N = 1e5+5;
    const int INF = 599518803;
    
    int n, opt, x;
    struct NODE
    {
        NODE *fa;
        NODE *son[2];
        int siz;
        int num, cnt;
    }node[N];
    
    typedef NODE* Tree;
    Tree Root, now_node, null;
    
    inline void init()
    {
        Root = now_node = null = node;
        null->son[0] = null->son[1] = null;
    }
    
    inline int read()
    {
        char c = getchar(); int num = 0, f = 1;
        for(; !isdigit(c); c = getchar())
            f = c == '-' ? -1 : f;
        for(; isdigit(c); c = getchar())
            num = num * 10 + c - '0';
        return num * f;
    }
    
    
    inline Tree new_node(int num, Tree fa)
    {
        ++ now_node;
        now_node->siz = 1;
        now_node->num = num;
        now_node->fa = fa;
        now_node->son[0] = now_node->son[1] = null;
        return now_node;
    }
    
    inline bool getgx(Tree root)
    {
        return root->fa->son[1] == root;
    }
    
    inline void connect(Tree root, Tree fa, bool flag)
    {
        if(fa != null)
            fa->son[flag] = root;
        else
            Root = root;
        root->fa = fa;
    }
    
    inline void update(Tree root)
    {
        root->siz = root->son[0]->siz + root->son[1]->siz + root->cnt;
    }
    
    inline void rotate(Tree root)
    {
        Tree fa = root->fa;
        bool a = getgx(root), b = !a;
        connect(root->son[b], fa, a);
        connect(root, fa -> fa, getgx(fa));
        connect(fa, root, b);
        update(fa);
        update(root);
        if(root->fa == null)
            Root = root;
    }
    
    inline void splay(Tree root, Tree goal)
    {
        for(; root->fa != goal; rotate(root))
            if(root->fa->fa != goal)
                rotate(getgx(root) == getgx(root->fa) ? root->fa : root);
    }
    
    void insert(int num)
    {
        if(Root == null)
        {
            Root = new_node(num, null);
            Root->cnt = 1;
        }
        else
        {
            Tree root = Root;
            for(; root->num != num; root = root->son[num > root->num])
            {
                ++ (root->siz);
                if(root->son[num > root->num] == null)
                    root->son[num > root->num] = new_node(num, root);
            }
            ++ (root->cnt);
            splay(root, null);
        }
    }
    
    void erase(int num)
    {
        if(Root == null)
            return;
        else
        {
            Tree root = Root;
            for(;root != null && root->num != num; root = root->son[num > root->num]);
            if(root == null)
                return;
            splay(root, null);
            -- (root->cnt);
            if(!root->cnt)
            {
                if(root->son[0] != null)
                {
                    Tree tmp = root->son[0];
                    for(;tmp->son[1] != null; tmp = tmp->son[1]);
                    splay(tmp, null);
                    Root->son[1] = root->son[1];
                    if(Root->son[1] != null)
                        Root->son[1]->fa = Root;
                }
                else
                {
                    Root = root->son[1];
                    Root->fa = null;
                }
            }
        }
    }
    
    inline int query_rank(int num)
    {
        int rank = 0;
        for(Tree root = Root; root != null; root = root->son[num > root->num])
        {
            if(num == root->num)
                return rank + root->son[0]->siz + 1;
            if(num > root->num)
                rank += root->son[0]->siz + root->cnt;
        }
        return rank;
    }
    
    inline int query_num(int rank)
    {
        for(Tree root = Root; root != null; )
        {
            if(rank <= root->son[0]->siz)
                root = root->son[0];
            else if(rank > root->son[0]->siz + root->cnt)
                rank -= root->son[0]->siz + root->cnt, root = root->son[1];
            else
                return root->num;
        }
    }
    
    inline int query_pre(int x)
    {
        int pre = -INF;
        for(Tree root = Root; root != null; root = root->son[x > root->num])
        {
            if(x > root->num)
                pre = max(pre, root->num);
        }
        return pre;
    }
    
    inline int query_nxt(int x)
    {
        int nxt = INF;
        for(Tree root = Root; root != null; root = root->son[x >= root->num])
        {
            if(root->num > x)
                nxt = min(nxt, root->num);
        }
        return nxt;
    }
    
    int main()
    {
        init();
        n = read();
        for(int i = 1; i <= n; ++ i)
        {
            opt = read(), x = read();
            switch(opt)
            {
                case 1:
                    insert(x); break;
                case 2:
                    erase(x); break;
                case 3:
                    printf("%d
    ", query_rank(x)); break;
                case 4:
                    printf("%d
    ", query_num(x)); break;
                case 5:
                    printf("%d
    ", query_pre(x)); break;
                default:
                    printf("%d
    ", query_nxt(x));
            }
        }
        return 0;
    }
  • 相关阅读:
    #include <boost/shared_array.hpp>
    #include <boost/shared_ptr.hpp>
    #include <boost/scoped_array.hpp>
    df命令
    telnet命令
    sort 命令
    苏宁大数据面试题
    hive严格模式
    k-means伪代码
    vim编辑器
  • 原文地址:https://www.cnblogs.com/lovewhy/p/8503134.html
Copyright © 2020-2023  润新知