zoukankan      html  css  js  c++  java
  • bzoj 3224: Tyvj 1728 普通平衡树

    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.每个数的数据范围:[-2e9,2e9]

    Source

    平衡树

    考场弃疗,听说这个题可以用值域线段树水过去,于是无聊地打了一发。。。

    前4个操作是值域线段树的傻逼操作,然后最后两个的话,也是傻逼操作。。。

    x的前驱,查询x的排名kth,然后再查询排名为kth-1的数。。。

    x的后继,查询x的排名ktn和x的数量,然后再查询排名为kth+num的数。。

    权值离散化一下就好了。。。贼短。。。

    // MADE BY QT666
    #include<cstdio>
    #include<algorithm>
    #include<cmath>
    #include<iostream>
    #include<cstring>
    using namespace std;
    typedef long long ll;
    const int N=500050;
    int rt,ls[N*20],rs[N*20],sum[N],sz;
    int hsh[N],tot,n;
    struct data{
      int x,type;
    }q[N];
    void insert(int &x,int l,int r,int v,int type){
      if(!x) x=++sz;
      if(l==r){sum[x]+=type;return;}
      int mid=(l+r)>>1;
      if(v<=mid) insert(ls[x],l,mid,v,type);
      else insert(rs[x],mid+1,r,v,type);
      sum[x]=sum[ls[x]]+sum[rs[x]];
    }
    int query1(int x,int l,int r,int v){
      if(l==r) return 1;
      int mid=(l+r)>>1;
      if(v<=mid) return query1(ls[x],l,mid,v);
      else return sum[ls[x]]+query1(rs[x],mid+1,r,v);
    }
    int query2(int x,int l,int r,int k){
      if(l==r) {return l;}
      int mid=(l+r)>>1;
      if(sum[ls[x]]>=k) return query2(ls[x],l,mid,k);
      else return query2(rs[x],mid+1,r,k-sum[ls[x]]);
    }
    int query3(int x){
      int kth=query1(rt,1,tot,x);
      return query2(rt,1,tot,kth-1);
    }
    int query5(int x,int l,int r,int v){
      if(l==r) return sum[x];
      int mid=(l+r)>>1;
      if(v<=mid) return query5(ls[x],l,mid,v);
      else return query5(rs[x],mid+1,r,v);
    }
    int query4(int x){
      int kth=query1(rt,1,tot,x)+query5(rt,1,tot,x);
      return query2(rt,1,tot,kth);
    }
    int main(){
      scanf("%d",&n);
      for(int i=1;i<=n;i++){
        scanf("%d%d",&q[i].type,&q[i].x);
        if(q[i].type!=4) hsh[++tot]=q[i].x;
      }
      sort(hsh+1,hsh+1+tot);tot=unique(hsh+1,hsh+tot+1)-hsh-1;
      for(int i=1;i<=n;i++){
        if(q[i].type!=4) q[i].x=lower_bound(hsh+1,hsh+1+tot,q[i].x)-hsh;
      }
      for(int i=1;i<=n;i++){
        if(q[i].type==1) insert(rt,1,tot,q[i].x,1);
        if(q[i].type==2) insert(rt,1,tot,q[i].x,-1);
        if(q[i].type==3) printf("%d
    ",query1(rt,1,tot,q[i].x));
        if(q[i].type==4) printf("%d
    ",hsh[query2(rt,1,tot,q[i].x)]);
        if(q[i].type==5) printf("%d
    ",hsh[query3(q[i].x)]);
        if(q[i].type==6) printf("%d
    ",hsh[query4(q[i].x)]);
      }
      return 0;
    }
    

      

  • 相关阅读:
    jenkins:通过execute shell启动的进程会被杀死的问题
    Cacti:添加监控磁盘IO
    Linux:添加永久路由
    Linux:下载方式安装lrzsz
    Linux:Vmware安装linux虚拟机,桥接方式配置静态IP后重启网卡,提示:Error,some other host already uses address 10.252.252.21...
    Linux:安装rstatd,报错
    Linux:安装图形界面
    leetcode Median of Two Sorted Arrays
    算法导论 寻找第i小元素 9.2
    算法导论9.1-1
  • 原文地址:https://www.cnblogs.com/qt666/p/7249570.html
Copyright © 2011-2022 走看看