BZOJ_3685_普通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
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
权值线段树写的,感觉不是很慢。
唯一需要注意的是56操作时给出的x可能小于最小值/最大值,这时需要输出-1。
代码:
#include <stdio.h> #include <string.h> #include <algorithm> using namespace std; #define N 1000050 #define ls p<<1 #define rs p<<1|1 #define maxn (n-1) inline char nc() { static char buf[100000],*p1,*p2; return p1==p2&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++; } inline int rd() { register int x=0; register char s=nc(); while(s<'0'||s>'9') s=nc(); while(s>='0'&&s<='9') x=(x<<3)+(x<<1)+s-'0',s=nc(); return x; } int t[N<<2],n,m,now; void insert(int l,int r,int x,int v,int p) { if(l==r) { if(v==0) { if(t[p]==0) now++; t[p]=1; }else { if(t[p]==1) now--; t[p]=0; } return ; } int mid=(l+r)>>1; if(x<=mid) insert(l,mid,x,v,ls); else insert(mid+1,r,x,v,rs); t[p]=t[ls]+t[rs]; } int get_rank(int l,int r,int x,int p) { if(l==r) return 1; int mid=(l+r)>>1; if(x<=mid) return get_rank(l,mid,x,ls); else return get_rank(mid+1,r,x,rs)+t[ls]; } int get_x(int l,int r,int k,int p) { if(l==r) return l; int mid=(l+r)>>1; if(k<=t[ls]) return get_x(l,mid,k,ls); else return get_x(mid+1,r,k-t[ls],rs); } int calcmin(int l,int r,int p) { if(l==r) return l; int mid=(l+r)>>1; if(t[ls]) return calcmin(l,mid,ls); else return calcmin(mid+1,r,rs); } int calcmax(int l,int r,int p) { if(l==r) return l; int mid=(l+r)>>1; if(t[rs]) return calcmax(mid+1,r,rs); else return calcmax(l,mid,ls); } int exist(int l,int r,int x,int p) { if(l==r) return t[p]?1:-1; int mid=(l+r)>>1; if(x<=mid) return exist(l,mid,x,ls); else return exist(mid+1,r,x,rs); } int main() { n=rd(); m=rd(); int i,x,opt; for(i=1;i<=m;i++) { opt=rd(); if(opt!=3&&opt!=4) x=rd(); if(opt==1) { insert(0,maxn,x,0,1); }else if(opt==2) { insert(0,maxn,x,1,1); }else if(opt==3) { printf("%d ",now?calcmin(0,maxn,1):-1); }else if(opt==4) { printf("%d ",now?calcmax(0,maxn,1):-1); }else if(opt==5) { if(x<=calcmin(0,maxn,1)) puts("-1"); else { int k=get_rank(0,maxn,x,1)-1; printf("%d ",get_x(0,maxn,k,1)); } }else if(opt==6) { if(x>=calcmax(0,maxn,1)) puts("-1"); else { int k=get_rank(0,maxn,x+1,1); printf("%d ",get_x(0,maxn,k,1)); } }else { printf("%d ",exist(0,maxn,x,1)); } } }