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. My sql 日期格式化

    DATE_FORMAT() 函数用于以不同的格式显示日期/时间数据. 语法 DATE_FORMAT(date,format) select DATE_FORMAT(NOW(),'%Y-%m-%d %H ...

  2. nginx指定配制文件

    nginx启动: 未指定配制文件: ./nginx 指定配制文件: /usr/local/nginx/sbin/nginx -c /home/deploy/nginx-wz/conf/nginx.co ...

  3. Java IO总结之缓冲读入文件

    package com.io; import java.io.BufferedReader; import java.io.FileReader; import java.io.IOException ...

  4. 夺命雷公狗—angularjs—6—单条数据的遍历

    我们在实际的工作中常常会处理到一些数据的遍历,这些数据都是后端传到前端的,有些公司会让前端帮忙处理一点遍历的工作,废话不多说,直接上代: <!doctype html> <html ...

  5. 夺命雷公狗---DEDECMS----20dedecms取出栏目页对应的内容

    取出栏目页对应的内容 现在我们的栏目页面是可以完全正常跳转了,那么我们现在需要完成的就是让他的内容全部(电影,连续剧,综艺)分类的显示出来. 我们还是要使用{dede:arclist}标签来取出我们所 ...

  6. Android2.2快速入门 zz

    http://www.cnblogs.com/over140/archive/2010/09/27/1836567.html 前言 这是前段时间用于公司Android入门培训的资料,学习Android ...

  7. [php笔记]项目开发五个阶段/雇员管理系统

    zend 公司,管理PHP版本的升级. 功能强大, 官方推荐. (开发一个PHP项目) 软件开发的五个阶段. 1.创建一个项目(工程)2.设置该项目的路径3.创建一个文件test.php ***使用Z ...

  8. BPM 应用系统开发案例实战

    概述 IBM BPM 的前身是 Lombardi,是由 IBM 于 2009 年收购的产品,之后产品更名为 IBM WebSphere Lombardi Edition,目前最新版本称为 IBM BP ...

  9. XMl的解析简单的方法

    首先需要jia包 xstream-1.4.7.jar Vo类 package com.zld.day06_03zk3demo.bean; import java.io.Serializable; im ...

  10. 转载:JMS-ActiveMQ浅析

    ActiveMQ 即时通讯服务 浅析 一. 概述与介绍 ActiveMQ 是Apache出品,最流行的.功能强大的即时通讯和集成模式的开源服务器.ActiveMQ 是一个完全支持JMS1.1和J2EE ...