zoukankan      html  css  js  c++  java
  • Treap模板

    #include <iostream>
    #include <algorithm>
    #include <cstring>
    #include <string>
    #include <cstdio>
    #include <vector>
    using namespace std;
    
    #define RG register int
    #define LL long long
    
    template<typename elemType>
    inline void Read(elemType &T){
        elemType X=0,w=0; char ch=0;
        while(!isdigit(ch)) {w|=ch=='-';ch=getchar();}
        while(isdigit(ch)) X=(X<<3)+(X<<1)+(ch^48),ch=getchar();
        T=(w?-X:X);
    }
    
    template<typename elemType,size_t MAX_SIZE=100010>
    struct Treap{
        struct TreapNode{
            elemType val;
            int rnd,size,num,son[2];
            int &operator[](int x){return son[x];}
        }T[MAX_SIZE];
        
        int root,cnt;
        Treap():root(0),cnt(0){}
    
        void push_up(int u){T[u].size=T[T[u][0]].size+T[T[u][1]].size+T[u].num;}
    
        int new_node(elemType val){//新建值为val的结点
            ++cnt;T[cnt].val=val;
            T[cnt].size=T[cnt].num=1;
            T[cnt].rnd=rand();
            return cnt;
        }
    
        void rotate(int &u,int d){//d=0左旋,d=1右旋
            int v=T[u][d^1];
            T[u][d^1]=T[v][d];
            T[v][d]=u;
            u=v;push_up(T[u][d]);push_up(u);
        }
    
        void insert_node(int &u,elemType val){
            if(!u){u=new_node(val);return;}
            if(T[u].val==val){++T[u].num;push_up(u);return;}
            int d=(val<T[u].val)?0:1;
            insert_node(T[u][d],val);
            if(T[u].rnd>T[T[u][d]].rnd) rotate(u,d^1);
            push_up(u);
        }
    
        void insert(elemType val){insert_node(root,val);}
    
        void delete_node(int &u,elemType val){
            if(!u) return;
            if(T[u].val==val){
                if(T[u].num>1){--T[u].num;push_up(u);return;}
                if(T[u][0] && !T[u][1]){rotate(u,1);delete_node(T[u][1],val);push_up(u);}
                else if(!T[u][0] && T[u][1]){rotate(u,0);delete_node(T[u][0],val);push_up(u);}
                else if(T[u][0] && T[u][1]){
                    if(T[T[u][0]].rnd<T[T[u][1]].rnd){rotate(u,1);delete_node(T[u][1],val);}
                    else{rotate(u,0);delete_node(T[u][0],val);}
                    push_up(u);
                }else u=0;
                return;
            }
            if(val<T[u].val) delete_node(T[u][0],val);
            else delete_node(T[u][1],val);
            push_up(u);
        }
        void delete_node(elemType val){delete_node(root,val);}
    
        int get_rank(int u,elemType val){
            if(!u) return 1;
            if(T[u].val==val) return T[T[u][0]].size+1;
            else if(val<T[u].val) return get_rank(T[u][0],val);
            return T[T[u][0]].size+T[u].num+get_rank(T[u][1],val);
        }
        int get_rank(elemType val){return get_rank(root,val);}
    
        int get_kth(int u,int kth){//返回第k大的结点
            if(u==0||kth>T[u].size) return 0;
            if(T[T[u][0]].size<kth && kth<=T[T[u][0]].size+T[u].num) return u;
            else if(kth<=T[T[u][0]].size) return get_kth(T[u][0],kth);
            return get_kth(T[u][1],kth-T[T[u][0]].size-T[u].num);
        }
        elemType get_kth_val(int kth){return T[get_kth(root,kth)].val;}
        //返回第k大的结点的值
    
        int get_predecessor(elemType val){//返回val的(严格)前驱结点
            int u=root,v;
            while(u){
                if(T[u].val<val){v=u;u=T[u][1];}
                else u=T[u][0];
            }
            return v;
        }
        elemType get_predecessor_val(elemType val){return T[get_predecessor(val)].val;}
        //返回val的(严格)前驱结点的值
    
        int get_successor(elemType val){//返回val的(严格)后继结点
            int u=root,v;
            while(u){
                if(val<T[u].val){v=u;u=T[u][0];}
                else u=T[u][1];
            }
            return v;
        }
        elemType get_successor_val(elemType val){return T[get_successor(val)].val;}
        //返回val的(严格)后继结点的值
    
        void output_tree(int u){//中序遍历Treap
            if(!u) return;
            output_tree(T[u][0]);
            cout<<T[u].val<<endl;
            output_tree(T[u][1]);
        }
    };
    Treap<int> Tree;
    int n;
    
    int main(){
        Read(n);
        for(RG i=1;i<=n;++i){
            int opt,x;
            Read(opt);Read(x);
            if(opt==1) Tree.insert(x);
            else if(opt==2) Tree.delete_node(x);
            else if(opt==3) printf("%d
    ",Tree.get_rank(x));
            else if(opt==4) printf("%d
    ",Tree.get_kth_val(x));
            else if(opt==5) printf("%d
    ",Tree.get_predecessor_val(x));
            else if(opt==6) printf("%d
    ",Tree.get_successor_val(x));
            else if(opt==7) Tree.output_tree(Tree.root);
        }
        return 0;
    }
    
  • 相关阅读:
    使用Zabbix服务端本地邮箱账号发送报警邮件及指定报警邮件操作记录
    分布式监控系统Zabbix--完整安装记录 -添加web页面监控
    如何为你的代码选择一个开源协议
    Android多开/分身检测
    squid介绍及其简单配置
    PS 切图、抠图
    AxureRP8实战手册
    墨刀 vs Axure RP
    Android 插件化 开发
    《Photoshop智能手机APP界面设计》学习笔记-转
  • 原文地址:https://www.cnblogs.com/AEMShana/p/13415090.html
Copyright © 2011-2022 走看看