堆/题解 P3378 【【模板】堆】
概念:
堆就是一颗二叉树,满足父亲节点总是比儿子节点大(小)。因此,堆也分为大根堆和小根堆,大根堆就是父亲节点比儿子节点大,小根堆正好相反。注意加粗的地方,是每一个节点哦!!!!!
还是直接看例题吧,这样讲起来更加生动。
上题:【模板】堆
解析:
这道题明显就是一个小根堆,那,怎么实现呢?热爱数组的我选择了数组实现明明就是指针不会。
操作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 【【模板】堆】的更多相关文章
- 最短路模板|堆优化Dijkstra,SPFA,floyd
Ⅰ:Dijkstra单源点最短路 1.1Dijkstra const int MAX_N = 10000; const int MAX_M = 100000; const int inf = 0x3f ...
- luogu P1552 [APIO2012]派遣 题解--可并堆/贪心
题目链接: https://www.luogu.org/problemnew/show/P1552 分析: 一开始愣是没看懂题,后面发现就是你要找一个树上点集使得各点权值之和小于\(M\),并且找一个 ...
- 堆排序(大顶堆、小顶堆)----C语言
堆排序 之前的随笔写了栈(顺序栈.链式栈).队列(循环队列.链式队列).链表.二叉树,这次随笔来写堆 1.什么是堆? 堆是一种非线性结构,(本篇随笔主要分析堆的数组实现)可以把堆看作一个数组,也可以被 ...
- 【转载】java项目中经常碰到的内存溢出问题: java.lang.OutOfMemoryError: PermGen space, 堆内存和非堆内存,写的很好,理解很方便
Tomcat Xms Xmx PermSize MaxPermSize 区别 及 java.lang.OutOfMemoryError: PermGen space 解决 解决方案 在 catalin ...
- 干货:JVM 堆内存和非堆内存
堆和非堆内存 按照官方的说法:"Java 虚拟机具有一个堆(Heap),堆是运行时数据区域,所有类实例和数组的内存均从此处分配.堆是在 Java 虚拟机启动时创建的."" ...
- JVM 堆内存和非堆内存
转载自:http://www.importnew.com/27645.html 堆和非堆内存 按照官方的说法:“Java 虚拟机具有一个堆(Heap),堆是运行时数据区域,所有类实例和数组的内存均从此 ...
- Java基础-Java中的堆内存和离堆内存机制
Java基础-Java中的堆内存和离堆内存机制 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任.
- 结构之美——优先队列基本结构(四)——二叉堆、d堆、左式堆、斜堆
实现优先队列结构主要是通过堆完成,主要有:二叉堆.d堆.左式堆.斜堆.二项堆.斐波那契堆.pairing 堆等. 1. 二叉堆 1.1. 定义 完全二叉树,根最小. 存储时使用层序. 1.2. 操作 ...
- hdu5795 A Simple Nim 求nim求法,打表找sg值规律 给定n堆石子,每堆有若干石子,两个人轮流操作,每次操作可以选择任意一堆取走任意个石子(不可以为空) 或者选择一堆,把它分成三堆,每堆不为空。求先手必胜,还是后手必胜。
/** 题目:A Simple Nim 链接:http://acm.hdu.edu.cn/showproblem.php?pid=5795 题意:给定n堆石子,每堆有若干石子,两个人轮流操作,每次操作 ...
随机推荐
- Java 第十一届 蓝桥杯 省模拟赛 凯撒密码加密
凯撒密码加密 题目 问题描述 给定一个单词,请使用凯撒密码将这个单词加密. 凯撒密码是一种替换加密的技术,单词中的所有字母都在字母表上向后偏移3位后被替换成密文.即a变为d,b变为e,-,w变为z,x ...
- Java实现 LeetCode 421 数组中两个数的最大异或值
421. 数组中两个数的最大异或值 给定一个非空数组,数组中元素为 a0, a1, a2, - , an-1,其中 0 ≤ ai < 231 . 找到 ai 和aj 最大的异或 (XOR) 运算 ...
- Java实现 POJ 2749 分解因数(计蒜客)
POJ 2749 分解因数(计蒜客) Description 给出一个正整数a,要求分解成若干个正整数的乘积,即a = a1 * a2 * a3 * - * an,并且1 < a1 <= ...
- Linux 工作管理
把进程放入后台 进程后加&,这时,进程在后台是运行的 tar -zcf etc.tar.gz /etc & 在执行程序时,快速按下ctrl+z快捷键,这时,进程在后台是停止的 查看后台 ...
- PAT A除以B
本题要求计算A/B,其中A 是不超过 1000 位的正整数,B 是 1 位正整数.你需要输出商数Q 和余数R,使得 A=B*Q+R 成立. 输入格式: 输入在一行中依次给出A 和B,中间以 1 空格分 ...
- Python学习之斐波那契数列实现篇
描述 一个斐波那契序列,F(0) = 0, F(1) = 1, F(n) = F(n-1) + F(n-2) (n>=2),根据n的值,计算斐波那契数F(n),其中0≤n≤1000. 输入 输入 ...
- ant构建Jmeter脚本的build文件配置(build.xml)
使用此构建文件可自动发送邮件 代码如下: <?xml version="1.0" encoding="UTF8"?> <project na ...
- Alink漫谈(六) : TF-IDF算法的实现
Alink漫谈(六) : TF-IDF算法的实现 目录 Alink漫谈(六) : TF-IDF算法的实现 0x00 摘要 0x01 TF-IDF 1.1 原理 1.2 计算方法 0x02 Alink示 ...
- ModelArts准备工作
说明: 本文是一个ModelArts准备工作文档,适用于初次使用ModelArts的用户.使用ModelArts之前,需要做如下工作:注册华为云账号.完成ModelArts全局配置.以及熟悉OBS相关 ...
- Docker_01
目录 1.1 Docker简介 1.1.1 为什么会有Docker的出现? 1.1.2 Docker理念 1.1.3 Docker or 虚拟机? 2.1 Docker安装 3.1 Docker基本使 ...