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

常规做法是用线段树,但根据这题的特点,还有很多其它数据结构可以用。

将线段树和trie结合,可得每个结点有8个子结点的线段树,每个结点压位维护8个子树是否非空。

预处理每个状态最左/右非空子树位置。

插入或删除时自底向上修改。查询前驱后继时自底向上找到前驱或后继所在区间再向下找到其具体位置。

最后加读入/输出优化,比zkw线段树略快一点,内存也省了很多。

#include<cstdio>
inline int read(){
char c=getchar();
int x=;
while(c>''||c<'')c=getchar();
while(c>=''&&c<='')
x=x*+c-'',c=getchar();
return x;
}
char str[];
inline void print(int x){
if(!x){
puts("");
return;
}
if(x<)putchar('-'),x=-x;
int p=;
while(x)str[p++]=x%+'',x/=;
while(p)putchar(str[--p]);
putchar();
}
bool d[];
unsigned char ds[][];
int lp[],rp[];
int ls[],rs[];
inline void ins(int x){
if(d[x])return;
d[x]=;
for(int i=;i<=;i++)ds[i][x>>i*]|=<<((x>>i*-)&);
}
inline void del(int x){
if(d[x])d[x]=;
else return;
for(int i=;i<=;i++)if(ds[i][x>>i*]^=<<((x>>i*-)&))return;
}
inline int minv(){
if(!ds[][])return -;
register int p=lp[ds[][]];
for(int i=;i;--i)p=(p<<)+lp[ds[i][p]];
return p;
}
inline int maxv(){
if(!ds[][])return -;
register int p=rp[ds[][]];
for(int i=;i;--i)p=(p<<)+rp[ds[i][p]];
return p;
}
inline int prv(int p){
if(!ds[][])return -;
register int s=ds[][p>>]&ls[p&];
if(s)return (p^(p&))|rp[s];
for(int i=;i<=;i++){
p>>=;
s=ds[i][p>>]&ls[p&];
if(s){
p=(p^(p&))|rp[s];
for(int j=i-;j;--j)p=(p<<)|rp[ds[j][p]];
return p;
}
}
return -;
}
inline int nxt(int p){
if(!ds[][])return -;
register int s=ds[][p>>]&rs[p&];
if(s)return (p^(p&))|lp[s];
for(int i=;i<=;i++){
p>>=;
s=ds[i][p>>]&rs[p&];
if(s){
p=(p^(p&))|lp[s];
for(int j=i-;j;--j)p=(p<<)|lp[ds[j][p]];
return p;
}
}
return -;
}
int n,m,a,b;
int main(){
for(int i=;i<;i++){
int j=;
while(!(i&<<j))++j;
lp[i]=j;
j=;
while(!(i&<<j))--j;
rp[i]=j;
}
for(int i=;i<;i++)ls[i]=>>-i,rs[i]=&(<<i+);
n=read();
m=read();
for(int i=;i<m;i++){
a=read();
if(a<){
b=read();
if(a==)ins(b);
else if(a==)del(b);
}else if(a>){
b=read();
if(a==)print(prv(b));
else if(a==)print(nxt(b));
else if(a==)puts(d[b]&&ds[][b>>]&<<(b&)?"":"-1");
}else if(a==)print(minv());
else if(a==)print(maxv()); }
return ;
}

最新文章

  1. Myeclipse的使用
  2. calender 软文
  3. css随记01编辑技巧,背景与边框
  4. 【POJ】3974 Palindrome
  5. Hadoop.2.x_HA部署
  6. ACCESS作为网站数据库的弊端
  7. web页面版权部分的显示问题
  8. 集合的知识点梳理(List,Set,不包含泛型)
  9. C# &quot;error CS1729: &#39;XXClass&#39; does not contain a constructor that takes 0 arguments&quot;的解决方案
  10. Mysql 作业(Scheduler)
  11. sublime 插件 和free 注册码
  12. 解决Admob Banner首次展示不显示的问题
  13. php以fastCGI的方式运行在iis下,遇到的文件系统权限问题及解决方法
  14. android解析网络json数据(1)
  15. RT-SA-2019-003 Cisco RV320 Unauthenticated Configuration Export
  16. 小学生噩梦——四则运算题库(python 全功能实现)
  17. selenium+python-文件下载(SendKeys)
  18. HttpWebRequest post 请求超时问题
  19. 模板倍增LCA 求树上两点距离 hdu2586
  20. Oracle中rownum用法警示

热门文章

  1. gitlba的搭建与使用
  2. 【DevExpress v17.2新功能预告】WinForms上的图表增强
  3. API - jQuery之操作cookie(转)
  4. anu - event
  5. Emacs矩形操作
  6. ZedGraph实时曲线实例
  7. XCODE中使用Main.Storyboard拉入控件并实现事件(Swift语言)
  8. Vue拖拽组件
  9. 20分钟打造你的Bootstrap站点
  10. Unity3D 发布APK安卓环境配置步骤、安装、教程(含Java/Android)(超全流程)