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

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
题解:vEB树什么的根本不会啊。。然后写个线段树吧。果断T了。。
抱着试试的心态加个读入优化。。然后就A了。。
代码:
#include<iostream>
#include<cstdio>
using namespace std;
struct use{int maxx,minn;}t[4000010],q;
int read(){  
    int x=0,f=1;char ch=getchar();  
    while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}  
    while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}  
    return x*f;  
} 
void insert(int k,int l,int r,int p,int v){
    int mid=(l+r)>>1;
    if (l==r&&l==p){if (v)t[k].maxx=t[k].minn=l;else {t[k].maxx=-1;t[k].minn=9999999;}return;}
    if (p<=mid) insert(k<<1,l,mid,p,v);else insert(k<<1|1,mid+1,r,p,v);
    t[k].maxx=max(t[k<<1].maxx,t[k<<1|1].maxx);
    t[k].minn=min(t[k<<1].minn,t[k<<1|1].minn);
}
use query(int k,int l,int r,int ll,int rr){
    use q,a,b;q.maxx=a.maxx=b.maxx=-1;q.minn=a.minn=b.minn=9999999;
    if (ll>rr) return q;int mid=(l+r)>>1;
    if (ll<=l&&r<=rr) return t[k];
    if (ll<=mid) a=query(k<<1,l,mid,ll,rr);if (rr>mid) b=query(k<<1|1,mid+1,r,ll,rr);
    q.minn=min(a.minn,b.minn);q.maxx=max(a.maxx,b.maxx);
    return q; 
}
int n,m,kind,x;
int main(){
   n=read();m=read();
   for (int i=0;i<=4000005;i++) {t[i].maxx=-1;t[i].minn=9999999;}; 
   for (int i=1;i<=m;i++){
     kind=read();
     if (kind==1){x=read();insert(1,0,n,x,1);}
     if (kind==2){x=read();insert(1,0,n,x,0);}
     if (kind==3){if (t[1].minn!=9999999)printf("%d\n",t[1].minn);else printf("-1\n");}
     if (kind==4) printf("%d\n",t[1].maxx);
     if (kind==5){x=read();q=query(1,0,n,0,x-1);printf("%d\n",q.maxx);}
     if (kind==6){
      x=read();q=query(1,0,n,x+1,n);
      if (q.minn!=9999999) printf("%d\n",q.minn);else printf("-1\n");
     }
     if (kind==7){
        x=read();q=query(1,0,n,x,x);if (q.maxx!=-1)printf("1\n");else printf("-1\n");
       }
     }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值