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的更多相关文章

  1. BZOJ 3685: 普通van Emde Boas树( 线段树 )

    建颗权值线段树就行了...连离散化都不用... 没加读入优化就TLE, 加了就A掉了...而且还快了接近1/4.... ---------------------------------------- ...

  2. bzoj3685普通van Emde Boas树 线段树

    3685: 普通van Emde Boas树 Time Limit: 9 Sec  Memory Limit: 128 MBSubmit: 1932  Solved: 626[Submit][Stat ...

  3. BZOJ_3685_普通van Emde Boas树_权值线段树

    BZOJ_3685_普通van Emde Boas树_权值线段树 Description 设计数据结构支持: 1 x  若x不存在,插入x 2 x  若x存在,删除x 3    输出当前最小值,若不存 ...

  4. Van Emde Boas Tree

    van Emde Boas trees 支持所有优先级优先级队列的操作,并且巧妙的是它对于SEARCH, INSERT,DELETE,MINIMUM,MAXMUN,SUCCESSOR,和PREDECE ...

  5. bzoj 3685: 普通van Emde Boas树

    3685: 普通van Emde Boas树 Description 设计数据结构支持:1 x  若x不存在,插入x2 x  若x存在,删除x3    输出当前最小值,若不存在输出-14    输出当 ...

  6. 【bzoj3685】普通van Emde Boas树 线段树

    普通van Emde Boas树 Time Limit: 9 Sec  Memory Limit: 128 MBSubmit: 1969  Solved: 639[Submit][Status][Di ...

  7. 算法导论笔记——第二十章 van Emde Boas树

    当关键字是有界范围内的整数时,能够规避Ω(lglgn)下界的限制,那么在类似的场景下,我们应弄清楚o(lgn)时间内是否可以完成优先队列的每个操作.在本章中,我们将看到:van Emde Boas树支 ...

  8. 浅谈 van Emde Boas 树——从 u 到 log log u 的蜕变

    本文参考算法导论完成. 模板题在此 QwQ 优化的过程比较长,还请读者耐心阅读,认真理解. 最初的想法 我会暴力! 用一个 \(size\) 数组维护每个元素出现的次数. 不细讲,时间复杂度 \(O( ...

  9. BZOJ3685: 普通van Emde Boas树

    显然这题的所有操作都可以用set,但是直接用set肯定要T,考虑到读入量较大,使用fread读入优化,就可以卡过去了. #include<bits/stdc++.h> using name ...

随机推荐

  1. sql 存储过程 分页

    ALTER PROCEDURE [dbo].[BrokerToLenderDataShow2]@Where VARCHAR(200), --查询条件 不含'where'字符,如id>10 and ...

  2. oracle的表空间

    创建表空间 1:创建单个文件的表空间 CREATE TABLESPACE SAMPLE LOGGING DATAFILE 'D:\11.dbf' SIZE 5M REUSE EXTENT MANAGE ...

  3. LIKE 某个变量

    declare i ); n number; begin i:='%D0FC02EAR11005%'; select po_header_id into n from po_headers_all w ...

  4. [CrunchBang]禁止“桌面上鼠标滚轮切换工作区桌面“

    鼠标滚轮切换虚拟桌面相关问题, 编辑 ~/.config/openbox/rc.xml 在   <context name="Desktop">段: <mouse ...

  5. yii2的windows下安装及前期步骤

    Yii2的安装(以生成basic目录为例) 第一步:服务器安装好后生成www目录,在该目录下新建yii2目录,把下载的compser.phar包放在该目录下 第二步:dos命令下进入项目目录 第三步: ...

  6. 使用git和github托管个人项目

    1.  安装 cygwin 和 cygwin 下的 git , 测试 git 命令可用;   参考: https://cygwin.com/install.html 2.  注册 github 账号: ...

  7. linux设备驱动归纳总结(四):4.单处理器下的竞态和并发【转】

    本文转载自:http://blog.chinaunix.net/uid-25014876-id-67005.html linux设备驱动归纳总结(四):4.单处理器下的竞态和并发 xxxxxxxxxx ...

  8. Python 的命令行参数处理 optparse->argparse

    optaprse自2.7版开始弃用:弃用optparse模块,不会进一步开发,将继续开发argparse模块作为替代. 但是用习惯了optparse,还是很好用的撒. optparse使用起来,相比旧 ...

  9. Nagios监控磁盘

    1.查看check_disk脚本 [oracle@rhel5 ~]$ /usr/local/nagios/libexec/check_disk --h check_disk v1.) Copyrigh ...

  10. 安装centos7.1 32bit时,没有可用的网络设备的解决方法

    安装的系统镜像文件:CentOS-7-i386-LiveGNOME-1511.iso 虚拟机版本: 问题: 原因: 原先我在这里选择的时候,以为自己安装的不是64位的,所以没有选择centos 64, ...