• 【bzoj3685】普通van Emde Boas树 线段树


    普通van Emde Boas树

    Time Limit: 9 Sec  Memory Limit: 128 MB
    Submit: 1969  Solved: 639
    [Submit][Status][Discuss]

    Description

    设计数据结构支持:
    1 x  若x不存在,插入x
    2 x  若x存在,删除x
    3    输出当前最小值,若不存在输出-1
    4    输出当前最大值,若不存在输出-1
    5 x  输出x的前驱,若不存在输出-1
    6 x  输出x的后继,若不存在输出-1
    7 x  若x存在,输出1,否则输出-1

    Input

    第一行给出n,m 表示出现数的范围和操作个数
    接下来m行给出操作
    n<=10^6,m<=2*10^6,0<=x<n

    Output

    Sample Input

    10 11
    1 1
    1 2
    1 3
    7 1
    7 4
    2 1
    3
    2 3
    4
    5 3
    6 2


    Sample Output

    1
    -1
    2
    2
    2
    -1

    HINT

    Source

    题解:

      很多数据结构都可以解决。

      权值线段树就可以。

      1 #include<iostream>
      2 #include<cstdio>
      3 #include<cstring>
      4 #include<algorithm>
      5 #include<cmath>
      6 
      7 #define N 3000007
      8 
      9 using namespace std;
     10 inline int read()
     11 {
     12     int x=0,f=1;char ch=getchar();
     13     while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
     14     while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
     15     return x*f;
     16 }
     17 
     18 int n,m;
     19 struct seg
     20 {
     21     int l,r,v;
     22 }t[N];
     23 
     24 void build(int k,int l,int r)
     25 {
     26     t[k].l=l;t[k].r=r;
     27     if(l==r)return;
     28     int mid=(l+r)>>1;
     29     build(k<<1,l,mid);
     30     build(k<<1|1,mid+1,r);
     31 }
     32 int mn(int k)
     33 {
     34     if(!t[k].v)return -1;
     35     int l=t[k].l,r=t[k].r;
     36     if(l==r)return l;
     37     if(t[k<<1].v)return mn(k<<1);
     38     else return mn(k<<1|1);
     39 }
     40 int mx(int k)
     41 {
     42     if(!t[k].v)return -1;
     43     int l=t[k].l,r=t[k].r;
     44     if(l==r)return l;
     45     if(t[k<<1|1].v)return mx(k<<1|1);
     46     else return mx(k<<1);
     47 }
     48 void insert(int k,int val)
     49 {
     50     int l=t[k].l,r=t[k].r;
     51     if(l==r){t[k].v=1;return;}
     52     int mid=(l+r)>>1;
     53     if(val<=mid)insert(k<<1,val);
     54     else insert(k<<1|1,val);
     55     t[k].v=t[k<<1].v+t[k<<1|1].v;
     56 }
     57 int find(int k,int val)
     58 {
     59     int l=t[k].l,r=t[k].r;
     60     if(l==r)
     61     {
     62         if(t[k].v)return 1;
     63         return -1;
     64     }
     65     int mid=(l+r)>>1;
     66     if(val<=mid)return find(k<<1,val);
     67     else return find(k<<1|1,val);
     68 }
     69 void del(int k,int val)
     70 {
     71     int l=t[k].l,r=t[k].r;
     72     if(l==r){t[k].v=0;return;}
     73     int mid=(l+r)>>1;
     74     if(val<=mid)del(k<<1,val);
     75     else del(k<<1|1,val);
     76     t[k].v=t[k<<1].v+t[k<<1|1].v;
     77 }
     78 int findpr(int k,int val)
     79 {
     80     if(val<0)return -1;
     81     if(!t[k].v)return -1;
     82     int l=t[k].l,r=t[k].r;
     83     if(l==r)return l;
     84     int mid=(l+r)>>1;
     85     if(val<=mid)return findpr(k<<1,val);
     86     else 
     87     {
     88         int t=findpr(k<<1|1,val);
     89         if(t==-1)return mx(k<<1);
     90         else return t;
     91     }
     92 }
     93 int findsu(int k,int val)
     94 {
     95     if(!t[k].v)return -1;
     96     int l=t[k].l,r=t[k].r;
     97     if(l==r)return l;
     98     int mid=(l+r)>>1;
     99     if(val>mid)return findsu(k<<1|1,val);
    100     else 
    101     {
    102         int t=findsu(k<<1,val);
    103         if(t==-1)return mn(k<<1|1);
    104         else return t;
    105     }
    106 }
    107 int main()
    108 {
    109     n=read(),m=read();
    110     build(1,0,n);
    111     int opt,x;
    112     for(int i=1;i<=m;i++)
    113     {
    114         opt=read();
    115         switch(opt)
    116         {
    117             case 1:x=read();if(find(1,x)==-1)insert(1,x);break;
    118             case 2:x=read();if(find(1,x)==1)del(1,x);break;
    119             case 3:printf("%d
    ",mn(1));break;
    120             case 4:printf("%d
    ",mx(1));break;
    121             case 5:x=read();printf("%d
    ",findpr(1,x-1));break;
    122             case 6:x=read();printf("%d
    ",findsu(1,x+1));break;
    123             case 7:x=read();printf("%d
    ",find(1,x));break;
    124         }
    125     }
    126 }
  • 相关阅读:
    第一次通过CLR Profile解决内存占用过高的问题
    未处理的异常
    var和dynamic的区别及如何正确使用dynamic?
    C#添加本地打印机
    CSS样式
    CSS选择器
    Winform 数据绑定
    [CLR via C#]值类型的装箱和拆箱
    Java Object
    设计模式_创建型模式
  • 原文地址:https://www.cnblogs.com/fengzhiyuan/p/8286983.html
Copyright © 2020-2023  润新知