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. struts2中的ognl详解,摘抄

    http://blog.csdn.net/tjcyjd/article/details/6850203     很全很细致,自己再分析原理进阶

  2. getResource().getPath()返回的路径空格变成了 %20

    this.getClass().getResource(“/”).getPath()使用者方法查看文件在服务器上的地址,但是地址中的空格会被转化为%20. 解决办法1: URI uri = new U ...

  3. emulator-arm.exe 已停止工作、 emulator-x86 已停止工作

    问题描述: emulator-arm.exe 已停止工作. emulator-x86 已停止工作.AVD模拟器启动一直黑屏.AVD模拟器启动一直显示andorid界面 解决方法: 1.   sdk的安 ...

  4. SlidingMenu实现app侧滑功能

    很多APP都有侧滑菜单的功能,部分APP左右都是侧滑菜单~SlidingMenu 这个开源项目可以很好帮助我们实现侧滑功能,如果对SlidingMenu 还不是很了解的童鞋,可以参考下本篇博客. 本片 ...

  5. linux strace

    yum install -y strace 若某一进程占用cpu高可以用strace -p pid进行跟踪查看 strace常用来跟踪进程执行时的系统调用和所接收的信号. 在Linux世界,进程不能直 ...

  6. django ORM model filter 条件过滤,及多表连接查询、反向查询,某字段的distinct

    版权归作者所有,任何形式转载请联系作者.作者:petanne(来自豆瓣)来源:https://www.douban.com/note/301166150/ 1.多表连接查询:感觉django太NX了. ...

  7. linux设备驱动归纳总结(八):2.总线、设备和驱动的关系【转】

    本文转载自:http://blog.chinaunix.net/uid-25014876-id-110295.html linux设备驱动归纳总结(八):2.总线.设备和驱动的关系 xxxxxxxxx ...

  8. ubunu下用命令设置壁纸

    ubunu下用命令设置壁纸: gsettings set org.gnome.desktop.background picture-uri “file:[fileName]” eg:gsettings ...

  9. C# HttpClient, 使用C#操作Web

    我们知道, .Net类库里提供了HttpWebRequest等类,方便我们编程与Web服务器进行交互. 但是实际使用中我们经常会遇到以下需求,基础类里没有直接提供相应的功能(WebClient类包含这 ...

  10. iOS 开发 证书总结 开发证书和生产证书的区别

    IOS开发 证书总结 开发者证书   ------>>  开发证书是你在真机推送时 用得, 生产证书是app 上架之后 推送给用户用的 首先你必须获得apple开发者证书,上图这个文件就是 ...