• [模板] Treap


    1. 插入x
    2. 删除x
    3. 查询排名为x的数
    4. 查询x的排名
    5. 求x的前驱、后继
    //Stay foolish,stay hungry,stay young,stay simple
    #include<iostream>
    #include<cstdio>
    #include<cstdlib>
    #include<cctype>
    using namespace std;
    
    const int MAXN=100010;
    const int INF=1<<29;
    
    int rd(){
        int ret=0,f=1;char c;
        while(c=getchar(),!isdigit(c))f=c=='-'?-1:1;
        while(isdigit(c)){
            ret=ret*10+c-'0';
            c=getchar();
        }
        return ret*f;
    }
    
    struct Treap{
        int l,r;
        int val,dat;
        int cnt,size;
    }node[MAXN];
    int tcnt,root,n;
    
    int add(int val){
        node[++tcnt].val = val;
        node[tcnt].dat = rand();
        node[tcnt].cnt = node[tcnt].size = 1;
        return tcnt;
    }
    
    void updata(int x){
        node[x].size =node[node[x].l].size+node[node[x].r].size+node[x].cnt;
    }
    
    void build(){
        add(-INF);add(INF);
        root=1;node[1].r=2;
        updata(root);
    }
    
    int GetRankByVal(int x,int val){
        if(x==0) return 0;
        if(val==node[x].val) return node[node[x].l].size+1;
        if(val<node[x].val) return GetRankByVal(node[x].l,val);
        return GetRankByVal(node[x].r,val)+node[node[x].l].size+node[x].cnt;
    }
    
    int GetValByRank(int x,int rank){
        if(x==0) return INF;
        if(node[node[x].l].size>=rank) return GetValByRank(node[x].l,rank);
        if(node[node[x].l].size+node[x].cnt>=rank) return node[x].val;
        return GetValByRank(node[x].r,rank-node[node[x].l].size-node[x].cnt);
    }
    
    void zig(int &x){
        int y=node[x].l;
        node[x].l=node[y].r;node[y].r=x;x=y;
        updata(node[x].r);updata(x);
    }
    
    void zag(int &x){
        int y=node[x].r;
        node[x].r = node[y].l;node[y].l = x;x=y;
        updata(node[x].l);updata(x);
    }
    
    void inst(int &x,int val){
        if(x==0){
            x=add(val);
            return;
        }
        if(val==node[x].val){
            node[x].cnt++;
            updata(x);
            return;
        }
        if(val<node[x].val){
            inst(node[x].l,val);
            if(node[x].dat<node[node[x].l].dat) zig(x);
        }else{
            inst(node[x].r,val);
            if(node[x].dat<node[node[x].r].dat) zag(x);
        }
        updata(x);
    }
    
    int GetPre(int val){
        int ans=1;
        int x=root;
        while(x){
            if(val==node[x].val){
                if(node[x].l>0){
                    x=node[x].l;
                    while(node[x].r>0) x=node[x].r;
                    ans=x;
                }
                break;
            }
            if(node[x].val<val&&node[x].val>node[ans].val) ans=x;
            x=val<node[x].val?node[x].l:node[x].r;
        }
        return node[ans].val;//ans
    } 
    
    int GetNext(int val){
        int ans=2;
        int x=root;
        while(x){
            if(val==node[x].val){
                if(node[x].r>0){
                    x=node[x].r;
                    while(node[x].l>0) x=node[x].l;
                    ans=x;
                }
                break;
            }
            if(node[x].val>val&&node[x].val<node[ans].val) ans=x;
            x=val<node[x].val?node[x].l:node[x].r;
        }
        return node[ans].val;
    }
    
    void remove(int &x,int val){
        if(x==0) return;
        if(val==node[x].val){
            if(node[x].cnt>1){
                node[x].cnt--;updata(x);
                return;
            }
            if(node[x].l||node[x].r){
                if(node[x].r==0||node[node[x].l].dat>node[node[x].r].dat){
                    zig(x),remove(node[x].r,val);
                }else{
                    zag(x),remove(node[x].l,val);
                }
                updata(x);
            }
            else x=0;
            return;
        }
        val<node[x].val?remove(node[x].l,val):remove(node[x].r,val);
        updata(x);
    }
    
    int main(){
        n=rd();
        build();
        while(n--){
            int opt,x;
            opt=rd();x=rd();
            switch(opt){
                case 1:
                    inst(root,x);
                    break;
                case 2:
                    remove(root,x);
                    break;
                case 3:
                    printf("%d
    ",GetRankByVal(root,x)-1);
                    break;
                case 4:
                    printf("%d
    ",GetValByRank(root,x+1));
                    break;
                case 5:
                    printf("%d
    ",GetPre(x));
                    break;
                case 6:
                    printf("%d
    ",GetNext(x));
                    break;
    
            }
        }
        return 0;
    }
    

    本文来自博客园,作者:GhostCai,转载请注明原文链接:https://www.cnblogs.com/ghostcai/p/9247423.html

  • 相关阅读:
    webpack 打包优化的四种方法(多进程打包,多进程压缩,资源 CDN,动态 polyfill)
    webpack loader实现
    Github配合Jenkins,实现vue等前端项目的自动构建与发布
    vue自定义指令,比onerror更优雅的方式实现当图片加载失败时使用默认图,提供三种方法
    echarts地图边界数据的实时获取与应用,省市区县多级联动【附最新geoJson文件下载】
    小程序webview调用微信扫一扫的“曲折”思路
    Nexus搭建Maven私服中央仓库
    使用Maven进行依赖管理和项目构建
    一、基础项目构建,引入web模块,完成一个简单的RESTful API
    Hession实现远程通讯(基于Binary-RPC协议)
  • 原文地址:https://www.cnblogs.com/ghostcai/p/9247423.html
Copyright © 2020-2023  润新知