• 【bzoj3224】【Tyvj 1728】 普通平衡树 树状数组


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

    数据范围:操作数$≤10^5$,$x≤10^9$。

    这一题用平衡树做的方法是显然的,然而平衡树太长太慢,我们考虑写一个优美一点的算法。

    首先先离散化所有读入的数(别离散化操作4!!!!)

    然后,插入和删除操作显然(直接在离散化后的x处,赋值+1或者-1即可)

    查询某个数的排名也是显然的。

    考虑查询排名为$x$如何高速完成,此处不妨设$x$为正整数。

    我们求一个最小的$p$,使得$2^p≥cnt$,其中$cnt$为树状数组的长度。

    设当前访问到的点为$id$(初始为$0$)

    我们每次查询$a[id+2^p]$上的值是否小于$x$,如果是$x$,那么$id+=2^p$,然后$x-=a[id]$。

    然后p--即可。

    最后输出$id+1$即是第$k$大的数。

    求前驱和后继:先求出给出的数是第几大的,然后$+1$或$-1$即可。

    代码奇短

     1 #include<bits/stdc++.h>
     2 #define M 200000
     3 #define lowbit(x) ((x)&(-x))
     4 using namespace std;
     5 int a[M]={0},c[M]={0},n,cnt=0,m;
     6 int op[M]={0},b[M]={0};
     7 void add(int x,int k){for(;x<=n;x+=lowbit(x)) a[x]+=k;}
     8 int sum(int x){int k=0;for(;x;x-=lowbit(x)) k+=a[x]; return k;}
     9 int getkth(int k){
    10     int id=0;
    11     for(int i=n;i;i>>=1){
    12         if(k>a[id+i]) 
    13         k-=a[id+i],id+=i;
    14     }
    15     return id+1;
    16 }
    17 int main(){
    18     scanf("%d",&m);
    19     for(int i=1;i<=m;i++){
    20         scanf("%d%d",op+i,b+i);
    21         if(op[i]!=4) c[++cnt]=b[i];
    22     }
    23     sort(c+1,c+cnt+1);
    24     for(int i=1;i<=m;i++)
    25     if(op[i]!=4) b[i]=lower_bound(c+1,c+cnt+1,b[i])-c;
    26     for(n=1;n<=cnt;n<<=1);    
    27     for(int i=1;i<=m;i++){
    28         if(op[i]==1) add(b[i],1);
    29         if(op[i]==2) add(b[i],-1);
    30         if(op[i]==3) printf("%d
    ",sum(b[i]-1)+1);
    31         if(op[i]==4) printf("%d
    ",c[getkth(b[i])]);
    32         if(op[i]==5) printf("%d
    ",c[getkth(sum(b[i]-1))]);
    33         if(op[i]==6) printf("%d
    ",c[getkth(sum(b[i])+1)]);
    34     }
    35 }    
  • 相关阅读:
    《软件需求模式》阅读笔记二
    《软件需求模式》阅读笔记一
    《编写有效用例》阅读笔记三
    《编写有效用例》阅读笔记二
    《编写有效用例》阅读笔记一
    《软件需求十步走》阅读笔记三
    英文一分钟自我介绍
    c语言面试常见题
    docker
    LLDP
  • 原文地址:https://www.cnblogs.com/xiefengze1/p/9901838.html
Copyright © 2020-2023  润新知