您的位置:首页 > 其它

BZOJ3685 普通van Emde Boas树

2016-01-04 14:22 344 查看
题目链接: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线段树都没看懂,足以证明我智商拙急)彻底退役吧

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#define rep(i,l,r) for(int i=l; i<=r; i++)
#define clr(x,y) memset(x,y,sizeof(x))
#define travel(x) for(Edge *p=last[x]; p; p=p->pre)
using namespace std;
const int INF = 0x3f3f3f3f;
int n,m,f,x,M=0,cnt=0;
bool t[1<<21|1];
inline int read(){
int ans = 0, f = 1;
char c = getchar();
while (!isdigit(c)){
if (c == '-') f = -1;
c = getchar();
}
while (isdigit(c)){
ans = ans * 10 + c - '0';
c = getchar();
}
return ans * f;
}
inline void update(int x,int d){
if (!(d^t[x+M])) return;
cnt += d ? 1 : -1;
for(t[x+=M] = d, x >>= 1; x; x >>= 1)
t[x] = t[x<<1] | t[x<<1|1];
}
inline int getmin(int x){
if (!cnt) return 0;
for(;x <= M;){
x = t[x<<1] ? x << 1 : x << 1 | 1;
}
return x - M;
}
inline int getmax(int x){
if (!cnt) return 0;
for(;x <= M;){
x = t[x<<1|1] ? x << 1 | 1 : x << 1;
}
return x - M;
}
inline int pre(int x){
if (!cnt) return 0;
for(x += M; x != 1; x >>= 1){
if (x & 1 && t[x^1]){
x ^= 1; break;
}
}
if (x == 1) return 0;
return getmax(x);
}
inline int nxt(int x){
if (!cnt) return 0;
for(x += M; x != 1; x >>= 1){
if (!(x & 1) && t[x^1]){
x ^= 1; break;
}
}
if (x == 1) return 0;
return getmin(x);
}
inline void judge(int x){
printf(t[x+M] ? "1\n" : "-1\n");
}
int main(){
n = read(); m = read();
while (1 << M < n) M++; M = (1 << M) - 1;
rep(i,1,m){
f = read();
switch(f){
case 1: x = read() + 1; update(x,1); break;
case 2: x = read() + 1; update(x,0); break;
case 3: printf("%d\n",getmin(1) - 1); break;
case 4: printf("%d\n",getmax(1) - 1); break;
case 5: x = read() + 1; printf("%d\n",pre(x) - 1); break;
case 6: x = read() + 1; printf("%d\n",nxt(x) - 1); break;
case 7: x = read() + 1; judge(x); break;
}
}
return 0;
}


View Code
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: