左式堆

  • 一.序
  • 二.用处
  • 三.基本概念
  • 四.合并
  • 五.代码实现
    • (一).结构
    • (二).合并
    • (三).插入
    • (四).删除
    • (五).样例代码
  • 例题
    • (hdu 1512) Monkey King
      • Problem Description
      • Input
      • Output
      • 解析

一.序

强烈安利<数据结构与算法分析-c语言描述>这本书!!!
更好的讲解可阅读该书.或者看这位大佬的博客%%

二.用处

这个左式堆啊~直接当作可以合并的二叉堆来理解,这是再最好不过的了,其他和堆没啥区别.

三.基本概念

零路径长(null pathength)
Npl(X):
结点X到一个没有两个儿子的结点的最短路径的长度。
这里我们定义没有两个儿子的结点的Npl(x)=1;Npl(NULL) = 0。

左堆和堆一样,也具有结构性质和堆序性质。左堆的结构性质是指:对于堆中的每一个结点X,它的左儿子的零路径长要不小于其右儿子的零路径长。
堆序信息与堆的一样,即:最小的结点应该是根节点,鉴于我们希望子树也是堆,那么每个子树的根节点也应该是最小的
这一性质必然会导致左堆是一个极其不平衡的树。
书上原话

四.合并

每次合并都从右子树开始合并.这图我也看不大懂,大致理解就好了.反正代码写出来,感觉和图的方法没大关系

五.代码实现

(一).结构

typedef struct heap* nd;
struct heap {int d, npl;nd lson, rson;
}*root;

npl指距离,左右儿子lson,rson,d表示该节点值.

(二).合并

nd merge(nd p, nd ip)
{if (p == NULL)return ip;if (ip == NULL)return p;if (ip->d > p->d)     //堆,小根<,大根>swap(p, ip);if (p->lson == NULL)p->lson = ip;else {p->rson = merge(p->rson, ip);if (p->lson->npl < p->rson->npl)    //保证性质不变swap(p->lson, p->rson);p->npl = p->rson->npl + 1;  //合并后,根节点的npl距离取右儿子的距离+1}return p;
}

(三).插入

插入这个命令,可以理解为,一个单个数的堆,与大堆合并.
即把要插入的数当作一个堆,与要插入的堆合并即可.

nd insert(nd p, int x)
{nd ip = (nd)malloc(sizeof(struct heap));if (ip == NULL) {cout << "error insert" << endl;exit(65530);}ip->lson = ip->rson = NULL;ip->npl = 0, ip->d = x;return p = merge(p, ip);
}

(四).删除

删除堆首的值,可以理解为,将堆根节点的左右儿子分成两个堆,然后再合并成一个新的堆.

nd pop(nd p)
{if (p == NULL) {cout << "error pop" << endl;exit(65530);}nd lp = p->lson, rp = p->rson;free(p);return merge(lp, rp);
}

(五).样例代码

#ifndef NULL
#define NULL 0;
#endif
using namespace std;typedef struct heap* nd;
struct heap {int d, npl;nd lson, rson;
}*root;
void close(nd p)
{if (p == NULL)return;close(p->lson),close(p->rson);delete(p);
}
nd merge(nd p, nd ip)
{if (p == NULL)return ip;if (ip == NULL)return p;if (ip->d > p->d)     //堆的小根<,大根>swap(p, ip);if (p->lson == NULL)p->lson = ip;else {p->rson = merge(p->rson, ip);if (p->lson->npl < p->rson->npl)swap(p->lson, p->rson);p->npl = p->rson->npl + 1;}return p;
}
nd pop(nd p)
{if (p == NULL) {cout << "error pop" << endl;exit(65530);}nd lp = p->lson, rp = p->rson;free(p);return merge(lp, rp);
}
nd insert(nd p, int x)
{nd ip = (nd)malloc(sizeof(struct heap));if (ip == NULL) {cout << "error insert" << endl;exit(65530);}ip->lson = ip->rson = NULL;ip->npl = 0, ip->d = x;return p = merge(p, ip);
}

例题

(hdu 1512) Monkey King

http://acm.hdu.edu.cn/showproblem.php?pid=1512

Problem Description

Once in a forest, there lived N aggressive monkeys. At the beginning, they each does things in its own way and none of them knows each other. But monkeys can’t avoid quarrelling, and it only happens between two monkeys who does not know each other. And when it happens, both the two monkeys will invite the strongest friend of them, and duel. Of course, after the duel, the two monkeys and all of there friends knows each other, and the quarrel above will no longer happens between these monkeys even if they have ever conflicted.
Assume that every money has a strongness value, which will be reduced to only half of the original after a duel(that is, 10 will be reduced to 5 and 5 will be reduced to 2).
And we also assume that every monkey knows himself. That is, when he is the strongest one in all of his friends, he himself will go to duel.

Input

There are several test cases, and each case consists of two parts.
First part: The first line contains an integer N(N<=100,000), which indicates the number of monkeys. And then N lines follows. There is one number on each line, indicating the strongness value of ith monkey(<=32768).
Second part: The first line contains an integer M(M<=100,000), which indicates there are M conflicts happened. And then M lines follows, each line of which contains two integers x and y, indicating that there is a conflict between the Xth monkey and Yth.

Output

For each of the conflict, output -1 if the two monkeys know each other, otherwise output the strongness value of the strongest monkey in all friends of them after the duel.
Sample Input
5
20
16
10
10
4
5
2 3
3 4
3 5
4 5
1 5
Sample Output
8
5
5
-1
10
Author
JIANG, Yanyan
Source
ZOJ 3rd Anniversary Contest
Recommend
linle

解析

一开始有n只孤独的猴子,然后他们要打m次架,每次打架呢,都会拉上自己朋友最牛叉的出来跟别人打,打完之后战斗力就会减半,每次打完架就会成为朋友(正所谓不打不相识o(∩_∩)o)。问每次打完架之后那俩猴子最牛叉的朋友战斗力还有多少,若朋友打架就输出-1.

并查集+可并堆
每次猴子和猴子打架做朋友,就并在一起.
每次要打架就查一下是不是在一起的朋友,不是就打架,是就输出-1.

在经历了无数次re和mle后,我把close函数删了==,遗留的指针遗留就遗留吧.就ac了…wtf

#include <iostream>
#include <algorithm>
#include<cstring>
#include <cstdio>
#ifndef NULL
#define NULL 0;
#endif
using namespace std;typedef struct heap* nd;
struct heap {int d, npl;nd lson, rson;
}*root;
struct vec {int d,fa;nd p;vec() {d = 0, p = NULL;}
}a[101000];
void close(nd p)
{if (p == NULL)return;close(p->lson);close(p->rson);delete(p);
}
nd merge(nd p, nd ip)
{if (p == NULL)return ip;if (ip == NULL)return p;if (ip->d > p->d)     //堆的小根<,大根>swap(p, ip);if (p->lson == NULL)p->lson = ip;else {p->rson = merge(p->rson, ip);if (p->lson->npl < p->rson->npl)swap(p->lson, p->rson);p->npl = p->rson->npl + 1;}return p;
}
nd pop(nd p)
{if (p == NULL) {cout << "error pop" << endl;exit(65530);}nd lp = p->lson, rp = p->rson;free(p);return merge(lp, rp);
}
nd insert(nd p, int x)
{nd ip = (nd)malloc(sizeof(struct heap));if (ip == NULL) {cout << "error insert" << endl;exit(65530);}ip->lson = ip->rson = NULL;ip->npl = 0, ip->d = x;return p = merge(p, ip);
}
int top(nd p)
{return p->d;
}
int ffa(int x)
{if (x == a[x].fa)return x;return a[x].fa=ffa(a[x].fa);
}
int read()
{int x = 0, f = 1; char c = getchar();while (c<'0' || c>'9') {if (c == '-')f = -1;c = getchar();}while (c >= '0'&&c <= '9') {x = x * 10 + c - '0';c = getchar();}return x * f;
}
int main()
{int n, m;while (~scanf("%d",&n)) {for (int i = 1; i <= n; i++) {a[i].d=read();a[i].fa = i;a[i].p = insert(a[i].p, a[i].d);}m=read();for (int i = 1; i <= m; i++) {int x, y, fx, fy;x=read(),y=read();fx = ffa(x), fy = ffa(y);if (fx != fy) {a[fy].fa = fx;int num1 = top(a[fx].p) / 2, num2 = top(a[fy].p) / 2;a[fx].p = pop(a[fx].p);a[fy].p = pop(a[fy].p);a[fx].p = a[fy].p = merge(a[fx].p, a[fy].p);a[fx].p = a[fy].p = insert(a[fx].p, num1);a[fx].p = a[fy].p = insert(a[fx].p, num2);cout << top(a[fx].p) << endl;}elsecout << -1 << endl;}for (int i = 1; i <= n; i++) a[i].p = NULL;}return 0;
}

蒟蒻的ACM数据结构(五)-左式堆相关推荐

  1. 蒟蒻的ACM数据结构(一)-线段树

    浅谈线段树的指针写法 一.基本概念 二.代码实现与基本操作 0.基础数据结构 1.建树 built函数 2. 单点查询 3.单点修改 4.区间查询 5.区间修改 三.优化 (一). Lazy-Tag懒 ...

  2. 蒟蒻的ACM数据结构(四)-单调队列和单调栈

    单调队列和单调栈 一.概念 二.实现 三.题目 单调队列 洛谷P1886 滑动窗口 解析 单调栈 [GXOI/GZOI2019]与或和 解析 POJ3250 Bad Hair Day 解析 POJ 2 ...

  3. 【数据结构与算法】左式堆的Java实现

    引言 二叉堆是对优先队列的一种高效实现,左式堆是针对二叉堆合并操作困难的缺点,而提出的另外一种优先队列实现方式. 线性结构合并困难是显而易见的,而二叉堆那样高效的支持合并操作而且只使用一个数组更是难得 ...

  4. 结构之美——优先队列基本结构(四)——二叉堆、d堆、左式堆

    实现优先队列结构主要是通过堆完成,主要有:二叉堆.d堆.左式堆.斜堆.二项堆.斐波那契堆.pairing 堆等. 1. 二叉堆 1.1. 定义 完全二叉树,根最小. 存储时使用层序. 1.2. 操作 ...

  5. 左式堆(左高树)实现

    左式堆是满足如下性质的二叉树(最小堆序): 要么为空树,要么根节点的左右子树均为左式堆,且根节点的关键码值小于等于左右子树所有节点的关键码值,此外左子树代表的左式堆的零路径长度大于等于右子树代表的左式 ...

  6. 【数据结构】二叉堆、TOP K 问题

    二叉堆.TOP K 问题 堆(Heap) 堆的出现,思考? 堆简介 二叉堆(Binary Heap) 获取最大值 最大堆 - 添加 最大堆 - 添加优化 最大堆 - 删除 replace 最大堆 – ...

  7. 蒟蒻的五周总结(解释引用)《挑战》

    一:尺取法: 解释摘自:(12条消息) 尺取法 - 详解 + 例题模板(全)_lxt_Lucia的博客-CSDN博客_尺取法 引用:顾名思义,像尺子一样取一段,借用挑战书上面的话说,尺取法通常是对数组 ...

  8. 蒟蒻吃药计划-治疗系列 #round6 数据结构初步-指针|链表|结构体

    今天小蒟蒻我学习了一丁点儿关于数据结构的东西,现在我来和大家昏响昏响. %%%WEY神犇神速切火题 更新中 转载于:https://www.cnblogs.com/Fraction/p/8477739 ...

  9. 二本蒟蒻的带牌退役感言(感谢两年来的acm经历)

    TP 20年10月 20年 - 21年 寒假 22年开始,大二下 暑假后,怎么就大三了,时间好快 第47届icpc杭州站 尾声 润~ 20年10月 一个高考发挥失常的蒟蒻来到了化大.他带着不甘和兴奋走 ...

最新文章

  1. Oracle自治事务
  2. python正则表达式,看完这篇文章就够了...
  3. 在div中显示html_HTML基础知识之DIV
  4. tar打包排除某个文件夹
  5. 电脑组装笔记:手把手教你如何自己组装电脑
  6. java 抽象类与接口理解
  7. 支付宝澄清使用华为方舟编译器;三星苹果遭遇集体诉讼;PHP 7.4.0 beta4 发布 | 极客头条...
  8. 使用Source Insight查看Android Framework 源码
  9. [附源码]Java计算机毕业设计SSM宠物管理系统
  10. Linux -- dos2unix、unix2dos
  11. coreldraw快速撤回_CDR X8撤销、重做与重复操作方法介绍
  12. 关于2015年春运增开旅客列车的公告
  13. 同一计算机打印机无法连接,共享打印机无法连接怎么办 共享打印机无法连接解决方法【图文教程】...
  14. 有限域(3)——多项式环的商环构造有限域
  15. 指尖心跳,通过手指测量心率波形
  16. 对象、继承、封装、多态、抽象类的组合应用:编写工资系统,实现不同类型员工(多态)的按月发放工资。如果当月出现某个Employee对象的生日,则将在该雇员的工资上增加100元发给他。
  17. 水鱼五笔编码练习系统
  18. linux 系统 DeepIn 安装网卡驱动RTL8812BU
  19. unity机器学习入门栗子之3D平衡球
  20. 基于python+mysql超市信息管理系统(附完整源代码)

热门文章

  1. Photoshop简单案例(9)——利用PS去水印的四种方法
  2. win xp 有效注册码
  3. MIUI中无法获取所有短信的坑
  4. 海量数据的KNN分类、Kmeans聚类
  5. Command failed with error 10107: ‘not master‘ on server 10.2.2.139:27017. Closed connection
  6. C++变体数据类型—— VARIANT
  7. linux查看python是否安装成功,肿么查看linux中是否安装supervisor
  8. Java 解码 H264 格式视频流中的图片
  9. 中软实习---批量删除和搜索,过滤器和权限管理---7.24-7.26
  10. 12306登录(略详细)