winner tree 胜者树
在树形选择排序中,利用锦标赛思想建立的树称为胜者树。
1、每个非终端节点存储的是左右孩子节点中的优胜者。
2、通过减少比较次数,提高效率。
3、胜者树就是一颗特殊的线段树。
一、构建树
Procedure buildmint; 复杂度 O(n)
var i,j,k:longint;
begin
i:=N; j:=N+n-; { 其中 N 为大于等于 n 的最小 2 次方数 }
while i> do
begin
k:=i;
while k<j do
begin
f[k div ]:=min(f[k],f[k+]);
k:=k+;
end;
if j and = then f[j div ]:=f[j];
i:=i div ; j:=j div ;
end;
end;
二、查询
核心思想:自下向上,奇偶缩进。
Function findmin(x,y:longint):longint; 复杂度 O(logn)
var i,j,k,r:longint;
begin
i:=x+N-; j:=y+N-; r:=i;
while i<=j do
begin
if (f[r]>f[i]) then r:=i;
if (f[r]>f[j]) then r:=j;
if (i and =) then inc(i);
if (j and =) then dec(j);
i:=i shr ; j:=j shr ;
end; exit(f[r]);
while r<N do
if (f[r]=f[r*]) then r:=r* else r:=r*+;
exit(r-N+);
end;
三、更新
核心思想:自下而上,更新父节点。
胜者树不擅长更新,因为,某个结点更新的时候,它还需要跟兄弟结点比较。更新频繁的情况,用败者树。
四、败者树
败者树是胜者树的一种变体。在败者树中,用父结点记录其左右子结点进行比赛的败者,而让胜者参加下一轮的比赛。败者树的根结点记录的是败者,需要加一个结点来记录整个比赛的胜利者。采用败者树可以简化重构的过程。
典型应用:多路归并排序,可以减少比较次数。
五、代码实现胜者树
poj2328 http://poj.org/problem?id=2823
Description
The array is [1 3 -1 -3 5 3 6 7], and k is 3.
Window position | Minimum value | Maximum value |
---|---|---|
[1 3 -1] -3 5 3 6 7 | -1 | 3 |
1 [3 -1 -3] 5 3 6 7 | -3 | 3 |
1 3 [-1 -3 5] 3 6 7 | -3 | 5 |
1 3 -1 [-3 5 3] 6 7 | -3 | 5 |
1 3 -1 -3 [5 3 6] 7 | 3 | 6 |
1 3 -1 -3 5 [3 6 7] | 3 | 7 |
Your task is to determine the maximum and minimum values in the sliding window at each position.
Input
Output
Sample Input
8 3
1 3 -1 -3 5 3 6 7
Sample Output
-1 -3 -3 -3 3 3
3 3 5 5 6 7
Source
#include <iostream>
#include <cmath> using namespace std; const int MX = ; int n, k;
int a[MX], minRes[MX], maxRes[MX];
int treeMin[*MX], treeMax[*MX];
int N; //构建一颗winner tree,tree用数组存储,根结点是数组的第二个结点,即A[1]
//叶子结点是原始数组。树的最左结点的下标是2的指数
void build() {
int i = N, j = N+n-;
while (i > ) {
int t = i;
while (t < j) {
treeMin[t/] = min(treeMin[t], treeMin[t+]);
treeMax[t/] = max(treeMax[t], treeMax[t+]);
t += ;
}
if ((j&) == ) {//下标j是偶数,说明这个结点是落单的
treeMin[j/] = treeMin[j];
treeMax[j/] = treeMax[j];
}
i = i>>;
j = j>>;
}
} int query(int x, int y) {
int i=x+N, j=y+N, t = i;
while (i <= j) {
if (treeMin[t] > treeMin[i]) t = i;
if (treeMin[t] > treeMin[j]) t = j;
if ((i&) == ) i++;
if ((j&) == ) j--;
i = i>>;
j = j>>;
}
//return treeMin[t];
while (t < N) {
if (treeMin[t] == treeMin[t*]) t = t*;
else t = t*+;
}
return treeMin[t];
//return t - N;
} void work() {
for (int i=; i<n-k+; i++) {
int x=N+i, y=x+k-, t=x, r=x;
while (x<=y) {
if (treeMin[t] > treeMin[x]) t = x;
if (treeMin[t] > treeMin[y]) t = y;
if (treeMax[r] < treeMax[x]) r = x;
if (treeMax[r] < treeMax[y]) r = y;
if ((x&) == ) x++;
if ((y&) == ) y--;
x = x>>;
y = y>>;
}
minRes[i] = treeMin[t];
maxRes[i] = treeMax[r];
}
} void printRes() {
for (int i=; i<n-k+; i++) {
if (i!=) cout<<" ";
cout<<minRes[i];
}
cout<<endl;
for (int i=; i<n-k+; i++) {
if (i!=) cout<<" ";
cout<< maxRes[i];
}
cout<<endl;
} int calN(int x) {
int i = ;
while (i < x) {
i = i<<;
}
return i;
} void printTree() {
cout << "min winner tree:" << endl;
for (int i=; i< n+N; i++) {
cout << treeMin[i] << " ";
}
cout << endl << "max winner tree:" << endl;
for (int i=; i<n + N; i++) {
cout << treeMax[i] << " ";
}
cout << endl;
} int main()
{
cin >> n >> k;
N = calN(n);
for (int i=; i<n; i++) {
cin >> a[i];
treeMax[N+i] = treeMin[N+i] = a[i];
} build(); //printTree(); work();
printRes(); //cout<<"query:"<< query(0, 2)<<endl; //cout << "Hello world!" << endl;
return ;
}
winner tree 胜者树的更多相关文章
- Mysql存储引擎之TokuDB以及它的数据结构Fractal tree(分形树)
在目前的Mysql数据库中,使用最广泛的是innodb存储引擎.innodb确实是个很不错的存储引擎,就连高性能Mysql里都说了,如果不是有什么很特别的要求,innodb就是最好的选择.当然,这偏文 ...
- 页面设计--Tree目录树
Tree目录树控件属性: 根据数据集合来配置相应的信息 加载模式有自动加载.自定加载 web中显示效果图:
- [转] Splay Tree(伸展树)
好久没写过了,比赛的时候就调了一个小时,差点悲剧,重新复习一下,觉得这个写的很不错.转自:here Splay Tree(伸展树) 二叉查找树(Binary Search Tree)能够支持多种动态集 ...
- CJOJ 1976 二叉苹果树 / URAL 1018 Binary Apple Tree(树型动态规划)
CJOJ 1976 二叉苹果树 / URAL 1018 Binary Apple Tree(树型动态规划) Description 有一棵苹果树,如果树枝有分叉,一定是分2叉(就是说没有只有1个儿子的 ...
- 【数据结构】B-Tree, B+Tree, B*树介绍 转
[数据结构]B-Tree, B+Tree, B*树介绍 [摘要] 最近在看Mysql的存储引擎中索引的优化,神马是索引,支持啥索引.全是浮云,目前Mysql的MyISAM和InnoDB都支持B-Tre ...
- poj 1741 Tree(树的点分治)
poj 1741 Tree(树的点分治) 给出一个n个结点的树和一个整数k,问有多少个距离不超过k的点对. 首先对于一个树中的点对,要么经过根结点,要么不经过.所以我们可以把经过根节点的符合点对统计出 ...
- 【POJ 2486】 Apple Tree(树型dp)
[POJ 2486] Apple Tree(树型dp) Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 8981 Acce ...
- C++胜者树
#include <iostream> #define MAX_VALUE 0x7fffffff using namespace std; //在这里我先反思一下.不知道怎么搞的,这个算法 ...
- MYSQL的B+Tree索引树高度如何计算
前一段被问到一个平时没有关注到有关于MYSQL索引相关的问题点,被问到一个表有3000万记录,假如有一列占8位字节的字段,根据这一列建索引的话索引树的高度是多少? 这一问当时就被问蒙了,平时这也只关注 ...
随机推荐
- 拼写纠正 Artificial Intelligence: A Modern Approach
Artificial Intelligence: A Modern Approach http://mindhacks.cn/2008/09/21/the-magical-bayesian-metho ...
- BeanNameViewResolver
As described in the documentation, BeanNameViewResolver resolves Views declared as beans. Usually yo ...
- Object C语法学习笔记(一)
1.@property与@synthesize配对使用. @property预编译指令的作用是自动声明属性的setter和getter方法. @synthesize 创建了该属性的访问代码 功能:让编 ...
- gradlew常用命令
./gradlew -v 查看版本 ./gradlew clean 清理.下载依赖 ./gradlew build 构建 libgdx项目中的gradlew run: ./gradlew deskt ...
- vb 修改数据库
Dim rscode As New ADODB.Recordset ................... Set RsCode = zwpub.DataMdb.DbConnect.Execute(& ...
- Selenium2学习-012-WebUI自动化实战实例-010-解决元素失效:StaleElementReferenceException: stale element reference: element is not attached to the page document
元素失效的想象提示信息如下图所示,此种问题通常是因为元素页面刷新之后,为重新获取元素导致的. 解决此类问题比较简单,只需要在页面刷新之后,重新获取一下元素,就可以消除此种错误了. 以下以易迅网搜索为例 ...
- MFC的简单加法器(二)
创建对话框主要分两大步,第一,创建对话框资源,主要包括创建新的对话框模板.设置对话框属性和为对话框添加各种控件:第二,生成对话框类,主要包括新建对话框类.添加控件变量和控件的消息处理函数等.鸡啄米在本 ...
- iOS工程如何支持64-bit
苹果在2014年10月20号发布了一条消息:从明年的二月一号开始,提交到App Store的应用必须支持64-bit.详细消息地址为:https://developer.apple.com/news/ ...
- iptables conntrack有什么用
iptables conntrack有什么用 http://zhidao.baidu.com/link?url=Eh5SRuplbsY_WkxxGkH4bpEyfMnHAe1RwJYSVlRYGKFU ...
- [BS-26] UIView、pop和Core Animation区别
UIView.pop和Core Animation区别 一.UIView.pop和Core Animation的主要区别 1. Core Animation的动画只能添加到layer上(layer.p ...