zoukankan      html  css  js  c++  java
  • 普通平衡树(bzoj 3224)

    Description

    您需要写一种数据结构(可参考题目标题),来维护一些数,其中需要提供以下操作:
    1. 插入x数
    2. 删除x数(若有多个相同的数,因只删除一个)
    3. 查询x数的排名(若有多个相同的数,因输出最小的排名)
    4. 查询排名为x的数
    5. 求x的前驱(前驱定义为小于x,且最大的数)
    6. 求x的后继(后继定义为大于x,且最小的数)

    Input

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

    Output

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

    Sample Input

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

    Sample Output

    106465
    84185
    492737

    HINT

    1.n的数据范围:n<=100000

    2.每个数的数据范围:[-1e7,1e7]

    数据如下http://pan.baidu.com/s/1jHMJwO2
    /*
      一个平衡树的模板写了一上午了,能犯的错误基本都犯了。。。
      首先没加哨兵,再就是删除操作时没有更新sz(这个巨坑),真是长记性了。 
    */
    #include<cstdio>
    #include<iostream>
    #define N 100010
    using namespace std;
    int son[N][2],fa[N],val[N],cnt[N],sz[N],m,rt,size;
    
    void pushup(int x){
        sz[x]=sz[son[x][0]]+sz[son[x][1]]+cnt[x];
    }
    
    void rotate(int x,int &k){
        int y=fa[x],z=fa[y],l,r;
        if(son[y][0]==x) l=0;else l=1;r=l^1;
        if(y==k) k=x;
        else {
            if(son[z][0]==y) son[z][0]=x;
            else son[z][1]=x;
        }
        fa[x]=z;fa[y]=x;fa[son[x][r]]=y;
        son[y][l]=son[x][r];son[x][r]=y;
        pushup(y);pushup(x);
    }
    
    void splay(int x,int &k){
        while(x!=k){
            int y=fa[x],z=fa[y];
            if(y!=k){
                if((son[y][0]==x)^(son[z][0]==y)) rotate(x,k);
                else rotate(y,k);
            }
            rotate(x,k);
        }
    }
    
    void insert(int v){
        int k=rt,y=0;
        while(k&&val[k]!=v) y=k,k=son[k][v>val[k]];
        if(k) cnt[k]++;
        else {
            k=++size;sz[k]=1;cnt[k]=1;fa[k]=y;val[k]=v;
            if(y) son[y][v>val[y]]=k;
        }
        splay(k,rt);
    }
    
    void find1(int v){//查找v的位置 
        int k=rt;if(!k)return;
        while(son[k][v>val[k]]&&val[k]!=v) 
          k=son[k][v>val[k]];
        splay(k,rt);
    }
    
    int find2(int x){//查找排名为x的数 
        x++;
        int k=rt;
        if(sz[k]<x)return 0;
        while(1){
            if(sz[son[k][0]]<x&&sz[son[k][0]]+cnt[k]>=x) return k;
            if(sz[son[k][0]]>=x) k=son[k][0];
            else x-=(sz[son[k][0]]+cnt[k]),k=son[k][1];
        }
        return k;
    }
    
    int nxt(int x,int f){
        find1(x);
        if((val[rt]>x&&f)||val[rt]<x&&!f) return rt;
        int p=son[rt][f];
        while(son[p][f^1]) p=son[p][f^1];
        return p;
    }
    
    void del(int v){
        find1(v);
        int x=rt,k;
        if(cnt[x]>1){cnt[x]--;sz[x]--;return;}
        if(!son[x][0]||!son[x][1]){
            rt=son[x][0]+son[x][1];
        }
        else {
            k=son[x][1];
            while(son[k][0])k=son[k][0];sz[k]+=sz[son[x][0]];
            fa[son[x][0]]=k;son[k][0]=son[x][0];
            rt=son[x][1];
        }
        fa[rt]=0;splay(k,rt);
    }
    
    int main(){
        insert(-0x7fffffff);insert(0x7fffffff);
        scanf("%d",&m);
         for(int i=1;i<=m;i++){
            int opt,x;scanf("%d%d",&opt,&x);
            if(opt==1) insert(x);
            if(opt==2) del(x);
            if(opt==3) find1(x),printf("%d
    ",sz[son[rt][0]]);
            if(opt==4) printf("%d
    ",val[find2(x)]);
            if(opt==5) printf("%d
    ",val[nxt(x,0)]);
            if(opt==6) printf("%d
    ",val[nxt(x,1)]);
        }
        return 0;
    }
  • 相关阅读:
    Model、ModelMap和ModelAndView的使用详解
    maven的pom.xml配置json依赖
    int和Integer的区别
    SSM 视频
    2018-1-25 PHP数组
    2018-1-25 PHP函数方法
    2018-1-22 PHP 变量和常量
    2018-1-21 复习
    2018-1-18 如何用html和css实现div的缓慢移动效果
    2018-1-17 js弹出div登录窗口
  • 原文地址:https://www.cnblogs.com/harden/p/6403543.html
Copyright © 2011-2022 走看看