博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
bzoj 3685: 普通van Emde Boas树
阅读量:5163 次
发布时间:2019-06-13

本文共 2451 字,大约阅读时间需要 8 分钟。

3685: 普通van Emde Boas树

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

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

Source

题解:

vEB树是什么东东???。。。。

按照题目描述用线段树做就好了。。。。

按0~n划分区间,记录区间中存在的数的个数。

提一下前驱的找法:

对于x,在整个区间内找x-1,每次递归的两次区间,如果x-1在左区间,那么直接递归左区间,如果在右区间,判断右区间有无答案,没有的话则当前答案是左区间内的最大值。

后继的话找法差不多。。

#include
#include
using namespace std;const int N=1000005;#define p1 (p<<1)#define p2 (p<<1|1)int n,m,i,p,x,t[N<<2];inline void read(int &v){ char ch,fu=0; for(ch='*'; (ch<'0'||ch>'9')&&ch!='-'; ch=getchar()); if(ch=='-') fu=1, ch=getchar(); for(v=0; ch>='0'&&ch<='9'; ch=getchar()) v=v*10+ch-'0'; if(fu) v=-v;}void update(int l,int r,int x,int y,int p){ if(l==r) { t[p]=y; return; } int mid=(l+r)>>1; if(x<=mid) update(l,mid,x,y,p1);else update(mid+1,r,x,y,p2); t[p]=t[p1]+t[p2];}int Min(int l,int r,int p){ if(!t[p]) return -1; if(l==r) return l; int mid=(l+r)>>1; if(t[p1]) return Min(l,mid,p1);else return Min(mid+1,r,p2);}int Max(int l,int r,int p){ if(!t[p]) return -1; if(l==r) return l; int mid=(l+r)>>1; if(t[p2]) return Max(mid+1,r,p2);else return Max(l,mid,p1);}int find(int l,int r,int x,int p){ if(!t[p]) return -1; if(l==r) return 1; int mid=(l+r)>>1; if(x<=mid) return find(l,mid,x,p1);else return find(mid+1,r,x,p2);}int pre(int l,int r,int x,int p){ if(x<0) return -1; if(!t[p]) return -1; if(l==r) return l; int mid=(l+r)>>1; if(x<=mid) return pre(l,mid,x,p1);else { int tmp=pre(mid+1,r,x,p2); if(tmp==-1) return Max(l,mid,p1);else return tmp; }}int last(int l,int r,int x,int p){ if(x>n) return -1; if(!t[p]) return -1; if(l==r) return l; int mid=(l+r)>>1; if(x>mid) return last(mid+1,r,x,p2);else { int tmp=last(l,mid,x,p1); if(tmp==-1) return Min(mid+1,r,p2);else return tmp; }}int main(){ read(n),read(m); for(i=1;i<=m;i++) { read(p); if(p==1) { read(x); update(0,n,x,1,1); } else if(p==2) { read(x); update(0,n,x,0,1); } else if(p==3) printf("%d\n",Min(0,n,1));else if(p==4) printf("%d\n",Max(0,n,1));else if(p==7) { read(x); printf("%d\n",find(0,n,x,1)); } else if(p==5) { read(x); printf("%d\n",pre(0,n,x-1,1)); } else { read(x); printf("%d\n",last(0,n,x+1,1)); } } return 0;}

  

转载于:https://www.cnblogs.com/lwq12138/p/5744771.html

你可能感兴趣的文章
【ADO.NET基础-数据加密】第一篇(加密解密篇)
查看>>
C语言基础小结(一)
查看>>
STL中的优先级队列priority_queue
查看>>
UE4 使用UGM制作血条
查看>>
浏览器对属性兼容性支持力度查询网址
查看>>
OO学习总结与体会
查看>>
虚拟机长时间不关造成的问题
查看>>
面试整理:Python基础
查看>>
Python核心编程——多线程threading和队列
查看>>
Program exited with code **** 相关解释
查看>>
植物大战僵尸中文年度版
查看>>
26、linux 几个C函数,nanosleep,lstat,unlink
查看>>
投标项目的脚本练习2
查看>>
201521123107 《Java程序设计》第9周学习总结
查看>>
Caroline--chochukmo
查看>>
iOS之文本属性Attributes的使用
查看>>
从.Net版本演变看String和StringBuilder性能之争
查看>>
Excel操作 Microsoft.Office.Interop.Excel.dll的使用
查看>>
解决Ubuntu下博通网卡驱动问题
查看>>
【bzoj2788】Festival
查看>>