van Emda Boas
van Emda Boas维护了一个整数集合[0,Max)(无重复),其中Max必须等于2的正整数次幂。它支持以下操作:
(1)插入一个数字;
(2)删除一个数字;
(3)询问某一个数字在不在这个集合中;
(4)询问集合的最大最小值;
(5)询问一个数字的前驱或者后继。
每个操作的复杂度最大为O(loglog(n))
#include <cmath>
#include <algorithm> /***
维护的集合范围为[0,MAXU-1]
MAXU必须为2的正整数次幂
MAXU<=2^30
***/ template<int MAXU>
class VanEmdeBoasTree
{
private: int m_inValidValue; struct TreeNode
{
int Min,Max; /**
u为2的某次幂
设u=2^k
若k为偶数 UpBit=k/2
若k为奇数 UpBit=(k+1)/2
DownBit=k-UpBit
**/
int u;
int UpBit;
int DownBit; TreeNode* summary;
TreeNode** cluster; /**
x的高UpBit位
**/
int high(int x)
{
return x>>DownBit;
} /**
x的低DownBit位
**/
int low(int x)
{
return x&((<<DownBit)-);
} int index(int hx,int lx)
{
return (hx<<DownBit)|lx;
}
};
TreeNode* m_root;
int m_MAXRANGE; /**
已知u=2^k 返回k
**/
int GetSumBit(const int u)
{
return int(log2(u)+0.5);
} void build(TreeNode* &root,const int u)
{
root->Min=m_inValidValue;
root->Max=m_inValidValue;
root->u=u; if(==u) return; const int k=GetSumBit(u);
root->UpBit=(k+)>>;
root->DownBit=k>>; root->summary=new TreeNode;
build(root->summary,<<root->UpBit); root->cluster=new TreeNode*[<<root->UpBit];
for(int i=;i<(<<root->UpBit);i++)
{
root->cluster[i]=new TreeNode;
build(root->cluster[i],<<root->DownBit);
}
} int GetMinValue(TreeNode *rt) { return rt->Min; }
int GetMaxValue(TreeNode *rt) { return rt->Max; } int getSuccessor(TreeNode* curNode,int x)
{
if(==curNode->u)
{
if(x==&&curNode->Max==) return ;
else return m_inValidValue;
}
else if(curNode->Min!=m_inValidValue&&x<curNode->Min)
{
return curNode->Min;
}
else
{
const int highX=curNode->high(x);
const int lowX=curNode->low(x); int MaxLow=GetMaxValue(curNode->cluster[highX]);
if(MaxLow!=m_inValidValue&&lowX<MaxLow)
{
return curNode->index(highX,
getSuccessor(curNode->cluster[highX],lowX));
}
else
{
int successCluster=getSuccessor(curNode->summary,highX);
if(successCluster==m_inValidValue) return m_inValidValue;
else
{
return curNode->index(successCluster,
GetMinValue(curNode->cluster[successCluster]));
}
}
}
} int getPredecessor(TreeNode* curNode,int x)
{
if(==curNode->u)
{
if(==x&&==curNode->Min) return ;
else return m_inValidValue;
}
else if(curNode->Max!=m_inValidValue&&x>curNode->Max)
{
return curNode->Max;
}
else
{
const int highX=curNode->high(x);
const int lowX=curNode->low(x); int MinLow=GetMinValue(curNode->cluster[highX]);
if(MinLow!=m_inValidValue&&lowX>MinLow)
{
return curNode->index(highX,
getPredecessor(curNode->cluster[highX],lowX));
}
else
{
int predCluster=getPredecessor(curNode->summary,highX);
if(predCluster==m_inValidValue)
{
if(curNode->Min!=m_inValidValue&&x>curNode->Min)
{
return curNode->Min;
}
else return m_inValidValue;
}
else
{
return curNode->index(predCluster,
GetMaxValue(curNode->cluster[predCluster]));
}
}
}
} void insertEmptyNode(TreeNode* curNode,int x)
{
curNode->Min=curNode->Max=x;
} void insert(TreeNode* curNode,int x)
{
if(curNode->Min==m_inValidValue)
{
insertEmptyNode(curNode,x);
return;
}
if(x==curNode->Min||x==curNode->Max) return;
if(x<curNode->Min)
{
std::swap(x,curNode->Min);
}
if(curNode->u>)
{
const int highX=curNode->high(x);
const int lowX=curNode->low(x);
if(GetMinValue(curNode->cluster[highX])==m_inValidValue)
{
insert(curNode->summary,highX);
insertEmptyNode(curNode->cluster[highX],lowX);
}
else
{
insert(curNode->cluster[highX],lowX);
}
}
if(x>curNode->Max) curNode->Max=x;
} void remove(TreeNode* curNode,int x)
{
if(curNode->Min==curNode->Max)
{
curNode->Min=curNode->Max=m_inValidValue;
return;
}
if(curNode->u==)
{
if(x==) curNode->Min=;
else curNode->Min=;
curNode->Max=curNode->Min;
return;
}
if(x==curNode->Min)
{
int firstCluster=GetMinValue(curNode->summary);
x=curNode->index(firstCluster,
GetMinValue(curNode->cluster[firstCluster]));
curNode->Min=x;
} const int highX=curNode->high(x);
const int lowX=curNode->low(x);
remove(curNode->cluster[highX],lowX);
if(GetMinValue(curNode->cluster[highX])==m_inValidValue)
{
remove(curNode->summary,highX);
if(x==curNode->Max)
{
int summaryMax=GetMaxValue(curNode->summary);
if(summaryMax==m_inValidValue) curNode->Max=curNode->Min;
else
{
curNode->Max=curNode->index(summaryMax,
GetMaxValue(curNode->cluster[summaryMax]));
}
}
}
else
{
if(x==curNode->Max)
{
curNode->Max=curNode->index(highX,
GetMaxValue(curNode->cluster[highX]));
}
}
} public: /**
构造函数需要提供类型的无效值
**/
VanEmdeBoasTree(const int inValidValue=-)
{
m_MAXRANGE=MAXU;
m_inValidValue=inValidValue;
m_root=new TreeNode;
build(m_root,MAXU);
} /**
key存在 返回1 否则返回0
**/
int isExist(int key)
{
if(key<||key>=MAXU) return ; TreeNode* curNode=m_root;
while()
{
if(key==curNode->Min||key==curNode->Max) return ;
else if(==curNode->u) return ;
else
{
TreeNode *nextNode=curNode->cluster[curNode->high(key)];
key=curNode->low(key);
curNode=nextNode;
}
}
} /**
查找key的后继 即大于key最小的值
若没有 返回m_inValidValue
**/
int getSuccessor(int key)
{
if(key<) return GetMinValue(m_root);
if(key>=m_MAXRANGE) return m_inValidValue;
return getSuccessor(m_root,key);
} /**
查找key的前驱 即小于key最大的值
若没有 返回m_inValidValue
**/
int getPredecessor(int key)
{
if(key<) return m_inValidValue;
if(key>=m_MAXRANGE) return GetMaxValue(m_root);
return getPredecessor(m_root,key);
} void insert(int key)
{
if(key<||key>=m_MAXRANGE) return;
insert(m_root,key);
} void remove(int key)
{
if(key<||key>=m_MAXRANGE) return;
remove(m_root,key);
} int GetMaxValue()
{
return GetMaxValue(m_root);
} int GetMinValue()
{
return GetMinValue(m_root);
}
};
van Emda Boas的更多相关文章
- BZOJ 3685: 普通van Emde Boas树( 线段树 )
建颗权值线段树就行了...连离散化都不用... 没加读入优化就TLE, 加了就A掉了...而且还快了接近1/4.... ---------------------------------------- ...
- bzoj3685普通van Emde Boas树 线段树
3685: 普通van Emde Boas树 Time Limit: 9 Sec Memory Limit: 128 MBSubmit: 1932 Solved: 626[Submit][Stat ...
- BZOJ_3685_普通van Emde Boas树_权值线段树
BZOJ_3685_普通van Emde Boas树_权值线段树 Description 设计数据结构支持: 1 x 若x不存在,插入x 2 x 若x存在,删除x 3 输出当前最小值,若不存 ...
- Van Emde Boas Tree
van Emde Boas trees 支持所有优先级优先级队列的操作,并且巧妙的是它对于SEARCH, INSERT,DELETE,MINIMUM,MAXMUN,SUCCESSOR,和PREDECE ...
- bzoj 3685: 普通van Emde Boas树
3685: 普通van Emde Boas树 Description 设计数据结构支持:1 x 若x不存在,插入x2 x 若x存在,删除x3 输出当前最小值,若不存在输出-14 输出当 ...
- 【bzoj3685】普通van Emde Boas树 线段树
普通van Emde Boas树 Time Limit: 9 Sec Memory Limit: 128 MBSubmit: 1969 Solved: 639[Submit][Status][Di ...
- 算法导论笔记——第二十章 van Emde Boas树
当关键字是有界范围内的整数时,能够规避Ω(lglgn)下界的限制,那么在类似的场景下,我们应弄清楚o(lgn)时间内是否可以完成优先队列的每个操作.在本章中,我们将看到:van Emde Boas树支 ...
- 浅谈 van Emde Boas 树——从 u 到 log log u 的蜕变
本文参考算法导论完成. 模板题在此 QwQ 优化的过程比较长,还请读者耐心阅读,认真理解. 最初的想法 我会暴力! 用一个 \(size\) 数组维护每个元素出现的次数. 不细讲,时间复杂度 \(O( ...
- BZOJ3685: 普通van Emde Boas树
显然这题的所有操作都可以用set,但是直接用set肯定要T,考虑到读入量较大,使用fread读入优化,就可以卡过去了. #include<bits/stdc++.h> using name ...
随机推荐
- struts2拦截器の简单实现(日语系统,请忽略乱码,重在实现)
1.创建类实现interceptor接口或者继承abstractinter~~~类 package com.mi.intercepter; import java.util.Date; import ...
- MyEclipse 死掉,JVM terminated. Exit code=1073807364
刚入手的新成员,刚开始使用myeclipse,是不是会有一大堆的问题,然后没有目标的走,这里有个小技巧,那就是如果做项目出现问题,一定要自己现在网络搜寻答案,网络时代.技术时代走到现在,一定有他的道理 ...
- 给uefi引导的方式安装archlinux
基本就是照着官方的wiki来的,不过官方的wiki的内容太杂了,或许我们需要的是一个瀑布似的流程. 其实大体上与mbr引导的方式类似,只凭借回忆说一下有区别的地方,等下一次有机会的时候再验证一下. 换 ...
- 白盒测试的学习之路----(四)搭建测试框架TestNG测试
TestNG是一个开源自动化测试框架; TestNG是类似于JUnit,但它不是一个JUnit扩展.它的灵感来源于JUnit.它的目的是优于JUnit的,尤其是当测试集成的类. TestNG消除了大部 ...
- 「LAMP」在ubuntu及其衍生版上 安装LAMP
在Ubuntu上安装LAMP 此种方法在Linux Mint 13/14/15/16/17.Ubuntu 12.10(Quantal Quetzal)和Ubuntu 13.04 Raring Ring ...
- iOS的第一个习作
首发:个人博客,更新&纠错&回复 代码在这里,对git还是使用不熟练,好在github新建项目后体贴地提示是不是要执行这样两句—— 这两句我肯定是背不住的,所以记一下. git rem ...
- 161111、NioSocket的用法(new IO)
今天先介绍NioSocket的基本用法,实际使用一般会采用多线程,后面会介绍多线程的处理方法. 从jdk1.4开始,java增加了新的io模式--nio(new IO),nio在底层采用了新的处理方式 ...
- Java中Properties类的使用
1.properties介绍 java中的properties文件是一种配置文件,主要用于表达配置信息,文件类型为*.properties,格式为文本文件,文件的内容是格式是"键=值&quo ...
- 使用Jconsole监控weblogic的配置方法
在项目中发现full gc非常频繁.达到了每分钟13次.我怀疑可能会有内存泄露.于是在晚上找了内存泄露的资料. 内存长期占用并导致系统不稳定一般有两种可能: 1. 对象被大量创建而且被缓存,在旧的对象 ...
- 分享:shell去掉linux配置文件的注释行
如何通过shell去掉Linux配置文件中的注释行呢? 本文给出两种解决方法,供大家参考. 方法1.使用grep -v "^#" 来去掉注释行,其中:-v 表示取反 ^# 表示注解 ...