【题解】洛谷P3378 堆(模板)

本文介绍了如何在正式比赛中使用堆这一数据结构,特别是小根堆。首先解释了小根堆的基本概念和手动构建过程,接着通过一个具体的题目——洛谷P3378,阐述了如何利用堆来解决问题。文中提到了在C++中直接调用标准库中的priority_queue来实现堆,同时提供了小根堆和大根堆的声明方式。对于自定义结构体的堆操作,文章建议重载比较运算符以满足题目需求。
摘要由CSDN通过智能技术生成

正式比赛时我们肯定不愿意手写堆,不过作为一道模板题,我们还是手写一下并体会堆的过程比较好。

小根堆的存在形式是一棵二叉树,根节点是最小的数。我们初始化树上所有节点的权值为INF。当要添加一个数x时,我们把当前编号+1,把数放在那儿,并记录下当前编号。然后不断将其与其父亲结点进行比较,如果小就交换,并让记录下来的该数的编号除以2。(对于二叉树来说 父亲节点编号为x,那么它两个儿子节点编号必然是x*2与x*2+1,代表左儿子与右儿子)。这样如果要找最小元素,只需输出根节点就行了,时间复杂度O(1)。如果要删除最小值,那我们记录根节点编号为1,并不断将其与其子节点比较,如果左比右大就让左代替,并把编号*2,反之右大右代替,编号*2+1。最后把根节点对应的编号变成INF。

#include<cstdio>
#include<iostream>
#include<cstring>
using namespace std;
const int maxn=1000010;
const int INF=0x3f3f3f3f;
int num[maxn*8];
int tot=0;
void add(int x)
{
	tot++;
	num[tot]=x;
	int q=tot;
	while(num[q]<num[q/2]&&q!=1)
	{
		swap(num[q],num[q/2]);
		q=q/2;
	}
}
int top()
{
	return num[1];
}
void pop()
{
	int q=1;
	while(num[q*2]!=INF||num[q*2+1]!=IN
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值