概念:

堆就是一颗二叉树,满足父亲节点总是比儿子节点大(小)。因此,堆也分为大根堆和小根堆,大根堆就是父亲节点比儿子节点大,小根堆正好相反。注意加粗的地方,是每一个节点哦!!!!!


还是直接看例题吧,这样讲起来更加生动。

上题:【模板】堆


解析:

这道题明显就是一个小根堆,那,怎么实现呢?热爱数组的我选择了数组实现明明就是指针不会。

操作1:添加一个数字

这里需要用到两个函数,一个insert函数,用来插入,一个ufix函数,用来更新。

void ufix(int i){
if(i <= 1) return; //如果都到根了,退出
if(h[i] < h[i / 2]){ //向上比较
swap(h[i] , h[i / 2]);
ufix(i / 2);
}
}
void insert(int x){
h[++tot] = x; //在末尾加上这个数,然后进行更新
ufix(tot); //对这个点进行更新
}

操作2:输出最小的数字(也就是堆顶)

直接输出堆顶就行了qwq。

if(x == 2) cout << h[1] << endl;

操作3:删除最小的数字(也就是堆顶)

这里也需要两个函数,一个delet函数,用来删除,一个dfix函数,用来更新。

void dfix(int i){
if(h[i] == 0x3fffffff) return; //如果已经越界了,就直接退出
int k;
if(h[i * 2] < h[i * 2 + 1]) k = i * 2; //比较左右儿子谁更优
else k = i * 2 + 1;
if(h[i] > h[k]){ //看自己是否需要更新
swap(h[i] , h[k]);
dfix(k);
}
}
void delet(){
swap(h[1] , h[tot]);
h[tot--] = 0x3fffffff; //删除
dfix(1);
}

完整代码

#include <bits/stdc++.h>
using namespace std;
int n , tot = 0;
int h[1000010];
void ufix(int i){
if(i <= 1) return;
if(h[i] < h[i / 2]){
swap(h[i] , h[i / 2]);
ufix(i / 2);
}
}
void dfix(int i){
if(h[i] == 0x3fffffff) return;
int k;
if(h[i * 2] < h[i * 2 + 1]) k = i * 2;
else k = i * 2 + 1;
if(h[i] > h[k]){
swap(h[i] , h[k]);
dfix(k);
}
}
void insert(int x){
h[++tot] = x;
ufix(tot);
}
void delet(){
swap(h[1] , h[tot]);
h[tot--] = 0x3fffffff;
dfix(1);
}
int main(){
cin >> n;
fill(h + 1 , h + 1000010 + 1 , 0x3fffffff);
while(n--){
int x;
cin >> x;
if(x == 1){
cin >> x;
insert(x);
}else if(x == 2) cout << h[1] << endl;
else delet();
}
return 0;
}

其实优先队列可以直接A的(其内部就是堆实现嘛),但是自己手写一遍可以加深理解哦。

堆/题解 P3378 【【模板】堆】的更多相关文章

  1. 最短路模板|堆优化Dijkstra,SPFA,floyd

    Ⅰ:Dijkstra单源点最短路 1.1Dijkstra const int MAX_N = 10000; const int MAX_M = 100000; const int inf = 0x3f ...

  2. luogu P1552 [APIO2012]派遣 题解--可并堆/贪心

    题目链接: https://www.luogu.org/problemnew/show/P1552 分析: 一开始愣是没看懂题,后面发现就是你要找一个树上点集使得各点权值之和小于\(M\),并且找一个 ...

  3. 堆排序(大顶堆、小顶堆)----C语言

    堆排序 之前的随笔写了栈(顺序栈.链式栈).队列(循环队列.链式队列).链表.二叉树,这次随笔来写堆 1.什么是堆? 堆是一种非线性结构,(本篇随笔主要分析堆的数组实现)可以把堆看作一个数组,也可以被 ...

  4. 【转载】java项目中经常碰到的内存溢出问题: java.lang.OutOfMemoryError: PermGen space, 堆内存和非堆内存,写的很好,理解很方便

    Tomcat Xms Xmx PermSize MaxPermSize 区别 及 java.lang.OutOfMemoryError: PermGen space 解决 解决方案 在 catalin ...

  5. 干货:JVM 堆内存和非堆内存

    堆和非堆内存 按照官方的说法:"Java 虚拟机具有一个堆(Heap),堆是运行时数据区域,所有类实例和数组的内存均从此处分配.堆是在 Java 虚拟机启动时创建的."" ...

  6. JVM 堆内存和非堆内存

    转载自:http://www.importnew.com/27645.html 堆和非堆内存 按照官方的说法:“Java 虚拟机具有一个堆(Heap),堆是运行时数据区域,所有类实例和数组的内存均从此 ...

  7. Java基础-Java中的堆内存和离堆内存机制

    Java基础-Java中的堆内存和离堆内存机制 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任.

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

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

  9. hdu5795 A Simple Nim 求nim求法,打表找sg值规律 给定n堆石子,每堆有若干石子,两个人轮流操作,每次操作可以选择任意一堆取走任意个石子(不可以为空) 或者选择一堆,把它分成三堆,每堆不为空。求先手必胜,还是后手必胜。

    /** 题目:A Simple Nim 链接:http://acm.hdu.edu.cn/showproblem.php?pid=5795 题意:给定n堆石子,每堆有若干石子,两个人轮流操作,每次操作 ...

随机推荐

  1. 蓝桥杯(Java方法、详细解法分析)基础练习 阶乘计算

    问题描述 给定n和len,输出n!末尾len位. 输入格式 一行两个正整数n和len. 输出格式 一行一个字符串,表示答案.长度不足用前置零补全. 样例输入 6 5 样例输出 00720 数据规模和约 ...

  2. Java实现 蓝桥杯 算法训练 求平方和

    试题 算法训练 求平方和 问题描述 请用函数重载实现整型和浮点习型的两个数的平方和计算 输入格式 测试数据的输入一定会满足的格式. 2 2(2行2列,第1行整型,第2行浮点型) 输出格式 要求用户的输 ...

  3. Java实现 蓝桥杯 算法提高 三进制数位和

    算法提高 三进制数位和 时间限制:1.0s 内存限制:256.0MB 提交此题 问题描述 给定L和R,你需要对于每一个6位三进制数(允许前导零),计算其每一个数位上的数字和,设其在十进制下为S. 一个 ...

  4. java实现第四届蓝桥杯猜年龄

    猜年龄 题目描述 美国数学家维纳(N.Wiener)智力早熟,11岁就上了大学.他曾在1935~1936年应邀来中国清华大学讲学. 一次,他参加某个重要会议,年轻的脸孔引人注目.于是有人询问他的年龄, ...

  5. syslog客户端java实现

    //package com.tony.util; import java.io.*; import java.net.*; /** * UDP客户端程序,用于对服务端发送数据,并接收服务端的回应信息. ...

  6. let与var的一个重要区别

    我们先来看下面这一段代码 html代码 <ul> <li>sdfsdagsdgsa</li> <li>sdfsdagsdgsa</li> & ...

  7. [转] Linux下用文件IO的方式操作GPIO(/sys/class/gpio)

    点击阅读原文 一.概述 通过 sysfs 方式控制 GPIO,先访问 /sys/class/gpio 目录,向 export 文件写入 GPIO 编号,使得该 GPIO 的操作接口从内核空间暴露到用户 ...

  8. Excel 中将大于511的十进制数转换成二进制

    If number < -512 or if number > 511, DEC2BIN returns the #NUM! error value. 所以不能直接使用DEC2BIN函数. ...

  9. Git中的core.autocrlf选项

    项目的开发环境为Windows,在Linux环境下编译,使用Git进行版本控制. 在安装好Git和TortoiseGit后,从远端clone,遇到一个奇怪的问题,Shell脚本中的LF总是被替换成了C ...

  10. python常用模块-os

    得到当前工作目录,即当前Python脚本工作的目录路径: os.getcwd() 返回指定目录下的所有文件和目录名:os.listdir() 函数用来删除一个文件:os.remove() 删除多个目录 ...