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 }
View Code

posted on 2016-01-04 14:22  ACMICPC  阅读(520)  评论(0编辑  收藏  举报

导航