bzoj3685题解(普通van Emde Boas树)
来源:互联网 发布:麦田的守望者 知乎 编辑:程序博客网 时间:2024/05/16 07:26
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
Sample Input
10 11
1 1
1 2
1 3
7 1
7 4
2 1
3
2 3
4
5 3
6 2
Sample Output
1
-1
2
2
2
-1
By ZKY
Solution
几乎要成为黑历史了!调了半个下午。(一定是因为我是个蒟蒻)
和普通平衡树一样,不用upper_bound之类的东西的话平衡树我不会找前趋后继,因为当前结点可能不在平衡树里。我用了zkw线段树。
对于操作1和2,直接找叶子是不是为空,若是则单点修改(+1或-1);(O(logn))
对于操作3,可以从根出发,左边不空就走左边,空了就走右边,直至走到叶子,叶子为空输出-1;(O(logn)
操作4同理,从根出发,右边不空就走右边,空了就走左边,直至走到叶子,叶子为空输出-1;(O(logn))
今天用个正常点的求前趋后继的方法:
如果结点x是x的父亲的右子树(x&1 == 1),那x^1就是x的父亲的左子树;
如果结点x是x的父亲的左子树(x&1 == 0),那x^1就是x的父亲的右子树;
对于操作5,若x是x的父亲的右子树,则x的父亲的左子树中的最大值即为x的前趋。所以当x是x的父亲的左子树时,可以一直找x的父亲(x>>=1),直到x是右子树,实行操作4。若操作4得出-1,则说明x无前趋。若x一直走到根仍不是右子树,则x无前趋。
操作6也同理。(Olog2*n)
操作7,直接找叶子,若为空则输出-1,不为空则输出1;O(1)
总时间复杂度O(n+mlogn),空间复杂度O(n)
/*
Time:7312ms;
Memory:17188KB;
*/
Code:
#include<cstdio>#include<algorithm>using namespace std;int T[4194304], n, m, delta;inline void add(int p, int d) { for(T[p+=delta]+=d, p>>=1; p; p>>=1) T[p] = T[p<<1]+T[(p<<1)+1];}inline int querymin(int x) { if(T[x] == 0) return -1; int iter = x; while(iter <= delta) { if(T[iter<<1] != 0) iter <<= 1; else ++(iter<<=1); } return iter-delta-1;}inline int querymax(int x) { if(T[x] == 0) return -1; int iter = x; while(iter <= delta) { if(T[(iter<<1)+1] != 0) ++(iter<<=1); else iter<<=1; } return iter-delta-1;}inline int find(int x) { if(T[x+delta+1] != 0) return 1; else return -1;}inline int pred(int x) { int pos = x+delta+1; while(1) { if(pos == 1) return -1; if(pos&1 && T[pos^1]) return querymax(pos^1); pos>>=1; } return -1;}inline int succ(int x) { int pos = x+delta+1; while(1) { if(pos == 1) return -1; if(!(pos&1) && T[pos^1]) return querymin(pos^1); pos>>=1; } return -1;}int main() { int x, opt; scanf("%d%d", &n, &m); for(delta = 1; delta < n+1; delta<<=1); for(int i = 1; i <= m; ++i) { scanf("%d", &opt); switch(opt) { case 1 :scanf("%d", &x); if(find(x) == -1) add(x+1, 1); break; case 2 :scanf("%d", &x); if(find(x) == 1) add(x+1, -1); break; case 3 :printf("%d\n", querymin(1)); break; case 4 :printf("%d\n", querymax(1)); break; case 5 :scanf("%d", &x); printf("%d\n", pred(x)); break; case 6 :scanf("%d", &x); printf("%d\n", succ(x)); break; case 7 :scanf("%d", &x); printf("%d\n", find(x)); break; default:; } } return 0;}
- bzoj3685题解(普通van Emde Boas树)
- BZOJ3685 普通van Emde Boas树
- [BZOJ3685]普通van Emde Boas树
- BZOJ3685: 普通van Emde Boas树
- BZOJ3685普通van Emde Boas树
- BZOJ3685 普通van Emde Boas树
- bzoj3685: 普通van Emde Boas树
- BZOJ3685 普通 van Emde Boas 树 题解(vEB 树模板题)
- 【bzoj3685】【普通van Emde Boas树】【线段树】
- 【BZOJ】【P3685】【普通van Emde Boas树】【题解】【vEB树】
- BZOJ 3685 普通van Emde Boas树
- BZOJ 3685 普通van Emde Boas树
- van Emde Boas树
- BZOJ 3685 普通van Emde Boas树 ZKW线段树
- BZOJ 3685 普通van Emde Boas树 zkw线段树
- BZOJ 3685 普通van Emde Boas树 zkw线段树
- 【BZOJ 3685】普通van Emde Boas树【treap】
- bzoj 3685 普通van Emde Boas树(坑)
- 推荐大家一款在Mac上录制Gif动画的软件
- 最简单的基于libVLC的例子:最简单的基于libVLC的推流器
- 蓝桥杯--微生物增值
- iOS 自定义滑动返回和解决连续多次push,pop引起的crash问题
- edittext失去焦点
- bzoj3685题解(普通van Emde Boas树)
- JSONModel的原理
- LCA最近公共祖先 在线算法和离线算法 模板
- Nginx.conf 中状态信息
- mfc学习笔记(2)——vector容器类型
- VS2010中创建安装项目
- ZOJ 3818 Pretty Poem (暴力模拟 string(substr))
- 网络图片浏览器
- codeforces 24A Ring road