zoukankan      html  css  js  c++  java
  • 普通平衡树

    题目描述

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

    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 原名:普通平衡树

    在此鸣谢

    今天上课听了一下讲的treap,然后就根据之前写splay的“经验”yy了一下写法(为什么我不找个模板hhh),再然后调错2h+.......

    其他的和splay比较类似,就是每个节点多一个随机数权值,保证堆性质,这样每次插入就不用旋转到根了,

    直接转到父亲的随机权值比它小就行了;

    一开始被删除坑了,,,删除不仅要把点下沉到叶子,而且要把父亲到根路径上的所有点的size减去1。

    #include<bits/stdc++.h>
    #define ll long long
    #define maxn 100005
    using namespace std;
    int f[maxn],ch[maxn][2];
    int num[maxn],val[maxn];
    int tot=0,n,m,siz[maxn];
    int opt,pos,root;
    
    inline int get(int x){
        return ch[f[x]][1]==x;
    }
    
    inline void update(int x){
        siz[x]=1+siz[ch[x][0]]+siz[ch[x][1]];
    }
    
    inline void rotate(int x){
        int fa=f[x],ffa=f[fa],tp=get(x);
        ch[fa][tp]=ch[x][tp^1],f[ch[fa][tp]]=fa;
        ch[x][tp^1]=fa,f[fa]=x;
        f[x]=ffa;
        if(ffa) ch[ffa][ch[ffa][1]==fa]=x;
        if(root==fa) root=x;
        update(fa),update(x);
    }
    
    inline void up(int x){
        while(f[x]&&val[x]<val[f[x]]) rotate(x);
    }
    
    inline void down(int x){
        int u;
        while(ch[x][0]||ch[x][1]){
            if(!ch[x][0]||!ch[x][1]) u=ch[x][0]+ch[x][1];
            else if(val[ch[x][0]]<val[ch[x][1]]) u=ch[x][0];
            else u=ch[x][1];
            rotate(u);
        }
    }
    
    inline void ins(int x){
        if(!root){
            root=++tot,num[tot]=x;
            val[tot]=rand(),siz[tot]=1;
            return;
        }
        
        int now=root,fa;
        while(now){
            fa=now,siz[now]++,now=ch[now][x>num[now]];
        }
        
        num[++tot]=x,val[tot]=rand(),siz[tot]=1;
        f[tot]=fa,ch[fa][x>num[fa]]=tot,update(fa);
        up(tot);
    }
    
    inline int kth(int k){
        int now=root;
        while(now){
            if(k<=siz[ch[now][0]]) now=ch[now][0];
            else{
                k-=siz[ch[now][0]]+1;
                if(k<=0) return num[now];
                now=ch[now][1];
            }
        }
        return -1;
    }
    
    inline int rank(int x){
        int now=root,an=0;
        while(now){
            if(num[now]<x) an+=siz[ch[now][0]]+1,now=ch[now][1];
            else now=ch[now][0];
        }
        return an;
    }
    
    inline void dec_node(int x){
        while(x) siz[x]--,x=f[x];
    }
    
    inline void del(int x){
        int now=root;
        while(now){
            if(num[now]==x) break;
            now=ch[now][x>num[now]];
        }
        
        if(!now) return;
        
        down(now);
        if(now==root) root=0;
        ch[f[now]][get(now)]=0,dec_node(f[now]),f[now]=0;
    }
    
    inline int pre(int x){
        int now=root,mx=-1000000000;
        while(now){
            if(num[now]<x) mx=max(mx,num[now]),now=ch[now][1];
            else now=ch[now][0];
        }
        return mx;
    }
    
    inline int nxt(int x){
        int now=root,mn=1000000000;
        while(now){
            if(num[now]>x) mn=min(mn,num[now]),now=ch[now][0];
            else now=ch[now][1];
        }
        return mn;
    }
    
    int main(){
        srand(time(0));
        scanf("%d",&n);
        while(n--){
            scanf("%d%d",&opt,&pos);
            if(opt==1) ins(pos);
            else if(opt==2) del(pos);
            else if(opt==3) printf("%d
    ",rank(pos)+1);
            else if(opt==4) printf("%d
    ",kth(pos));
            else if(opt==5) printf("%d
    ",pre(pos));
            else printf("%d
    ",nxt(pos));
        }
        
        return 0;
    }
  • 相关阅读:
    一个ip对应多个域名多个ssl证书配置-Nginx实现多域名证书HTTPS,NGINX支持多个带SSL证书的网站同时部署在同一台服务器上
    SVN报错:Node remains in conflict显示冲突的解决办法
    阿里云上部署了zabbix,突然无法收到报警邮件的解决办法
    npm安装socket.io时报错的解决方法(npm WARN enoent ENOENT: no such file or directory, open '/usr/local/nodejs/bin/package.json')
    winscp以命令行方式同步服务器数据到PC机磁盘上
    在阿里云上无法使用mailx发送邮件的解决办法,验证可用。
    编译geth报错的解决方法 make: *** [geth] 错误 1
    ZABBIX 3.0 监控MongoDB性能【OK】
    print命令
    软件开发规范
  • 原文地址:https://www.cnblogs.com/JYYHH/p/8289684.html
Copyright © 2011-2022 走看看