BZOJ3685 普通van Emde Boas树
题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=3685
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
一搜题解好像没有人老老实实打vEB Tree,都是用ZKW线段树过的
于是就再看了一次ZKW线段树,讲稿《统计的力量》ppt:链接(百度文库)
(以前看过两次ZKW线段树都没看懂,足以证明我智商拙急)彻底退役吧
1 #include <iostream> 2 #include <cstdio> 3 #include <algorithm> 4 #include <cstring> 5 #define rep(i,l,r) for(int i=l; i<=r; i++) 6 #define clr(x,y) memset(x,y,sizeof(x)) 7 #define travel(x) for(Edge *p=last[x]; p; p=p->pre) 8 using namespace std; 9 const int INF = 0x3f3f3f3f; 10 int n,m,f,x,M=0,cnt=0; 11 bool t[1<<21|1]; 12 inline int read(){ 13 int ans = 0, f = 1; 14 char c = getchar(); 15 while (!isdigit(c)){ 16 if (c == '-') f = -1; 17 c = getchar(); 18 } 19 while (isdigit(c)){ 20 ans = ans * 10 + c - '0'; 21 c = getchar(); 22 } 23 return ans * f; 24 } 25 inline void update(int x,int d){ 26 if (!(d^t[x+M])) return; 27 cnt += d ? 1 : -1; 28 for(t[x+=M] = d, x >>= 1; x; x >>= 1) 29 t[x] = t[x<<1] | t[x<<1|1]; 30 } 31 inline int getmin(int x){ 32 if (!cnt) return 0; 33 for(;x <= M;){ 34 x = t[x<<1] ? x << 1 : x << 1 | 1; 35 } 36 return x - M; 37 } 38 inline int getmax(int x){ 39 if (!cnt) return 0; 40 for(;x <= M;){ 41 x = t[x<<1|1] ? x << 1 | 1 : x << 1; 42 } 43 return x - M; 44 } 45 inline int pre(int x){ 46 if (!cnt) return 0; 47 for(x += M; x != 1; x >>= 1){ 48 if (x & 1 && t[x^1]){ 49 x ^= 1; break; 50 } 51 } 52 if (x == 1) return 0; 53 return getmax(x); 54 } 55 inline int nxt(int x){ 56 if (!cnt) return 0; 57 for(x += M; x != 1; x >>= 1){ 58 if (!(x & 1) && t[x^1]){ 59 x ^= 1; break; 60 } 61 } 62 if (x == 1) return 0; 63 return getmin(x); 64 } 65 inline void judge(int x){ 66 printf(t[x+M] ? "1\n" : "-1\n"); 67 } 68 int main(){ 69 n = read(); m = read(); 70 while (1 << M < n) M++; M = (1 << M) - 1; 71 rep(i,1,m){ 72 f = read(); 73 switch(f){ 74 case 1: x = read() + 1; update(x,1); break; 75 case 2: x = read() + 1; update(x,0); break; 76 case 3: printf("%d\n",getmin(1) - 1); break; 77 case 4: printf("%d\n",getmax(1) - 1); break; 78 case 5: x = read() + 1; printf("%d\n",pre(x) - 1); break; 79 case 6: x = read() + 1; printf("%d\n",nxt(x) - 1); break; 80 case 7: x = read() + 1; judge(x); break; 81 } 82 } 83 return 0; 84 }