BZOJ3685 普通van Emde Boas树
2016-01-04 14:22
344 查看
题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=3685
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
接下来m行给出操作
n<=10^6,m<=2*10^6,0<=x<n
一搜题解好像没有人老老实实打vEB Tree,都是用ZKW线段树过的
于是就再看了一次ZKW线段树,讲稿《统计的力量》ppt:链接(百度文库)
(以前看过两次ZKW线段树都没看懂,足以证明我智商拙急)彻底退役吧
View Code
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
相关文章推荐
- [ACM]约瑟夫环
- 移动端滑动加载更多
- Makefile快速入门
- 黑马程序员————java基础之GUI
- object-c ubuntu下开发环境搭建
- JavaScript 表单验证
- Swift - Struct 與 Class 的差異性
- 【门面设计模式】的故事来源(Facade Pattern)
- 05_重新打开已有工程(随手记)
- 在Magento页面左边增加分类菜单
- Linq把一个DataTable根据一列去除重复数据
- myeclipse 在线生成注册码
- 机器学习中的算法(1)-决策树模型组合之随机森林与GBDT
- 按照优先级的顺序执行任务
- 关于C#中将数字转换为指定格式
- 为什么OSPF在广播网络里面,DD和LSR采用单播,而LSU hello采用组播。
- 23种设计模式知多少
- c语言中同一函数下不可以重复定义变量
- Javascript对象相关方法
- 傅里叶变换