zoukankan      html  css  js  c++  java
  • 洛谷 P3369 【模板】普通平衡树(Treap/SBT)

    题目描述


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

    1. 插入x数
    2. 删除x数(若有多个相同的数,因只删除一个)
    3. 查询x数的排名(排名定义为比当前数小的数的个数+1。若有多个相同的数,因输出最小的排名)
    4. 查询排名为x的数
    5. 求x的前驱(前驱定义为小于x,且最大的数)
    6. 求x的后继(后继定义为大于x,且最小的数)

    输入输出格式

    输入格式:

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

    输出格式:

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

    输入输出样例

    输入样例:

    10
    1 106465
    4 1
    1 317721
    1 460929
    1 644985
    1 84185
    1 89851
    6 81968
    1 492737
    5 493598

    输出样例:

    106465
    84185
    492737

    Splay 解析尚未完成 参见yyb dalao的博客

    丑陋的代码送上(yyb大佬的代码比我的漂亮多了):

    #ifndef SPLAY_TREE_HPP
    #define SPLAY_TREE_HPP
    #include<bits/stdc++.h>
    using namespace std;
    namespace Splay_tree
    {
        template<typename T>
        struct splay_node
        {
            T value;
            int size;
            int cnt;
            bool reverse;
            splay_node *father;
            splay_node *son[2];
            splay_node(){}
            splay_node(T v, splay_node *f=NULL)
                :value(v),cnt(1)
            {
                father=f;
                size=0;
                son[0]=son[1]=NULL;
            }
        };
    
        template<typename T, typename C=less<T> >
        class Splay
        {
            private:
                typedef splay_node<T> node;
                node *root;
                C small_to;
                bool big_to(T x, T y){return small_to(y,x);}
                bool equal_to(T x, T y){return !(small_to(x,y)||big_to(x,y));}
    
                inline bool son(node *f, node *s)
                {
                    return f->son[1]==s;
                }
                inline void rotate(node *t)
                {
                    node *f = t->father;
                    node *g = f->father;
                    bool a = son(f, t), b = !a;
                    f->son[a] = t->son[b];
                    if (t->son[b] != NULL)
                        t->son[b]->father = f;
                    t->son[b] = f;
                    f->father = t;
                    t->father = g;
                    if (g != NULL)
                        g->son[son(g, f)] = t;
                    else
                        root = t;
                    update(f);
                    update(t);
                }
    
                inline void splay(node *t, node *p)
                {
                    while (t->father != p)
                    {
                        node *f = t->father;
                        node *g = f->father;
                        if (g == p)
                            rotate(t);
                        else
                        {
                            if (son(g, f) ^ son(f, t)) rotate(t), rotate(t);
                            else rotate(f), rotate(t);
                        }
                    }
                    update(t);
                }
    
                inline T k_th(int k, node *f)
                {
                    int tmp;
                    node *t=root;
                    while(1)
                    {
                        int tmp=size(t->son[0])+t->cnt;
                        int sze=tmp-t->cnt;
                        if(k<=tmp&&sze<k) break;
                        else if(k<=sze) t=t->son[0];
                        else k-=tmp,t=t->son[1];
                    }
                    T ans=t->value;
                    return ans;
                }
                
                inline node* insert(T val, node *t)
                {
                    int b=big_to(val,t->value);
                    if(equal_to(val,t->value))
                    {
                        t->cnt++;
                        update(t);
                        return t;
                    }
                    if(t->son[b]==NULL)
                    {
                        t->son[b]=new node(val,t);
                        update(t->son[b]);
                        update(t);
                        return t->son[b];
                    }
                    else
                    {
                        node *ans=insert(val,t->son[b]);
                        update(t);
                        return ans;
                    }
                }
    
            public:
                Splay()
                {
                    root=NULL;
                }
                
                inline void insert(T val)
                {
                    if (root == NULL)
                    {
                        root = new node(val, NULL);
                        update(root);
                        return;
                    }
                    else
                    {
                        node *t = insert(val,root);
                        splay(t,NULL);
                    }
                }
    
                inline void erase(T val)
                {
                    node *t = root;
                    while(t)
                    {
                        if (equal_to(t->value,val))
                            break;
                        t = t->son[big_to(val,t->value)];
                    }
                    if (t != NULL)
                    {
                        splay(t, NULL);
                        if(t->cnt>1)
                        {
                            t->cnt--;
                            update(t);
                            return;
                        }
                        if (t->son[0] == NULL)
                        {
                            root = t->son[1];
                            if (root != NULL)
                            {
                                root->father = NULL;
                                update(root);
                            }
                        }
                        else
                        {
                            node *p = t->son[0];
                            while (p->son[1] != NULL)
                                p = p->son[1];
                            splay(p, t); root = p;
                            root->father = NULL;
                            p->son[1] = t->son[1];
                            update(p);
                            if (p->son[1] != NULL)
                                p->son[1]->father = p;
                        }
                    }
                }
    
                inline T pre(T val)
                {
                    T ans=pre_ptr(val)->value;
                    return ans;
                }
    
                inline T suc(T val)
                {
                    node *x = root;
                    insert(val);
                    node *t=root->son[1];
                    if(t==NULL) return T(NULL);
                    while(t->son[0]!=NULL) t=t->son[0];
                    erase(val);
                    T ans=t->value;
                    return ans;
                }
    
                inline T max_value()
                {
                    node *t=root;
                    while(t->son[1]!=NULL) t=t->son[1];
                    return t->value;
                }
    
                inline T min_value()
                {
                    node *t=root;
                    while(t->son[0]!=NULL) t=t->son[0];
                    return t->value;
                }
    
                inline T k_th(int k)
                {
                    return k_th(k,NULL);
                }
                
                inline int rank(T val)
                {
                    node *t=root;
                    while(!equal_to(t->value, val))
                        t=t->son[big_to(val,t->value)];
                    splay(t,NULL);
                    return size(t->son[0])+1;
                }
                
                inline void print()
                {
                    print(root);
                    puts("");
                }
    
            private:
            
                inline node* pre_ptr(T val)
                {
                    insert(val);
                    node *t=root->son[0];
                    if(t==NULL) return NULL;
                    while(t->son[1]!=NULL) t=t->son[1];
                    erase(val);
                    return t;
                }
            
                inline void print(node *t)
                {
                    if(t==NULL) return;
                    print(t->son[0]);
                    printf("%d ",t->value);
                    print(t->son[1]);
                }
                
                inline int size(node *t)
                {
                    return t == NULL ? 0 : t->size;
                }
    
                inline void update(node *t)
                {
                    t->size = t->cnt;
                    t->size += size(t->son[0]);
                    t->size += size(t->son[1]);
                }
        };
    }
    #endif
    
    int main()
    {
        using namespace Splay_tree;
        int n;
        Splay<int> tree;
        scanf("%d",&n);
        for(int i=1;i<=n;i++)
        {
            int ops;
            int x;
            scanf("%d%d",&ops,&x);
            switch(ops)
            {
                case 1:
                    tree.insert(x);
                    break;
                case 2:
                    tree.erase(x);
                    break;
                case 3:
                {
                    int t=tree.rank(x);
                    printf("%d
    ",t);
                    break;
                }
                case 4:
                {
                    int y=tree.k_th(x);
                    printf("%d
    ",y);
                    break;
                }
                case 5:
                    printf("%d
    ",tree.pre(x));
                    break;
                case 6:
                    int t=tree.suc(x);
                    printf("%d
    ",t);
                    break;
            }
        }
    }
    View Code
  • 相关阅读:
    paddlepaddle训练网络的基本流程二(进阶Paddle-detection框架)
    paddlepaddle训练网络的基本流程一(入门示例)
    redis常用操作命令
    mysql基础命令
    使用Gunicorn和nginx进行Flask服务部署
    如何测试(八)抖音 如何测试?
    全(十九)Jmeter 请求 之 遇到 cookie、token 处理方式(使用 正则表达式提取器 获取 然后在引用)
    全(十八)Jmeter 请求元件 之 JSON PATH 提取 响应结果
    全(十七)Jmeter 请求元件 之 正则表达式提取器 提取 响应结果、foreach循环控制器
    全(十六)Jmeter 请求 之 正则表达式
  • 原文地址:https://www.cnblogs.com/cj-xxz/p/7765987.html
Copyright © 2011-2022 走看看