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
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
-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");
}
}
}