题目大意:维护一种数据结构,支持以下操作:
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
这题卡Treap,要写线段树
ZKW大法好啊 可惜我这个沙茶又写挂了……
#include<cstdio> #include<cstring> #include<iostream> #include<algorithm> #define M 2100100 using namespace std; int n,m,q,tree[M]; void Add(int x) { x+=q; if(tree[x]) return ; for(;x;x>>=1) tree[x]++; } void Del(int x) { x+=q; if(!tree[x]) return ; for(;x;x>>=1) tree[x]--; } int Get_Min() { int x; if(!tree[1]) return 0; for(x=1;x<=q;x=tree[x<<1]?x<<1:x<<1|1); return x-q; } int Get_Max() { int x; if(!tree[1]) return 0; for(x=1;x<=q;x=tree[x<<1|1]?x<<1|1:x<<1); return x-q; } int Get_Pred(int x) { for(x+=q;x^1;x>>=1) if(x&1&&tree[x>>1]>tree[x]) break; if(x==1) return 0; for(x^=1;x<=q;x=tree[x<<1|1]?x<<1|1:x<<1); return x-q; } int Get_Secc(int x) { for(x+=q;x^1;x>>=1) if(~x&1&&tree[x>>1]>tree[x]) break; if(x==1) return 0; for(x^=1;x<=q;x=tree[x<<1]?x<<1:x<<1|1); return x-q; } int Exsist(int x) { return tree[x+q]?1:-1; } int main() { //freopen("3685.in","r",stdin); //freopen("3685.out","w",stdout); int i,p,x; cin>>n>>m; for(q=1;q<=n;q<<=1); for(i=1;i<=m;i++) { scanf("%d",&p); if(p==1) { scanf("%d",&x); Add(x+1); } if(p==2) { scanf("%d",&x); Del(x+1); } if(p==3) printf("%d\n",Get_Min()-1); if(p==4) printf("%d\n",Get_Max()-1); if(p==5) { scanf("%d",&x); printf("%d\n",Get_Pred(x+1)-1); } if(p==6) { scanf("%d",&x); printf("%d\n",Get_Secc(x+1)-1); } if(p==7) { scanf("%d",&x); printf("%d\n",Exsist(x+1)); } } }
BZOJ 3685 普通van Emde Boas树 ZKW线段树
原文地址:http://blog.csdn.net/popoqqq/article/details/40743703