洛谷 P3378 【模板】堆

洛谷 P3378 【模板】堆

【题目描述】

给定一个数列,初始为空,请支持下面三种操作:

给定一个整数 x,请将 x 加入到数列中。
输出数列中最小的数。
删除数列中最小的数(如果有多个数最小,只删除 1 个)。

【输入格式】

第一行是一个整数,表示操作的次数 n。
接下来 n 行,每行表示一次操作。每行首先有一个整数 op 表示操作类型。

若 op = 1,则后面有一个整数 x,表示要将 x 加入数列。
若 op = 2,则表示要求输出数列中的最小数。
若 op = 3,则表示删除数列中的最小数。如果有多个数最小,只删除 1 个。

【输出格式】

对于每个操作 2,输出一行一个整数表示答案。

【输入输出样例】

输入

5
1 2
1 5
2
3
2

输出

2
5

【AC代码】

手动建堆调整

#include <iostream>
#include <cstdio>
#include <queue>
#include <algorithm>
using namespace std;
const int maxn=1e6+5;
int heap[maxn],n=0;//最小堆(下标从1开始) 
void downAdjust(int low,int high)//向下调整 
{
	int i=low,j=i*2;
	while(j<=high)
	{
		if(j+1<=high&&heap[j+1]<heap[j])
			j++;
		if(heap[j]<heap[i])
		{
			swap(heap[j],heap[i]);
			i=j;
			j*=2;
		}
		else
			break;
	}
}
void createHeap()//建堆 
{
	for(int i=n/2;i>=1;i--)
		downAdjust(i,n);
}
void deleteTop()//删除堆顶元素 
{
	heap[1]=heap[n--];
	downAdjust(1,n);
}
void upAdjust(int low,int high)//向上调整 
{
	int i=high,j=i/2;
	while(j>=low)
	{
		if(heap[j]>heap[i])
		{
			swap(heap[j],heap[i]);
			i=j;
			j/=2;
		}
		else
			break;
	}
}
void insert(int x)//插入元素 
{
	heap[++n]=x;
	upAdjust(1,n);
}
int main()
{
	ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
	int t,a,b;
	cin>>t;
	while(t--)
	{
		cin>>a;
		if(a==1)
		{
			cin>>b;
			insert(b);
		}
		if(a==2)
			cout<<heap[1]<<endl;
		if(a==3)
			deleteTop();
	}
	return 0;
}

STL heap

#include <iostream>
#include <cstdio>
#include <queue>
#include <algorithm>
using namespace std;
const int maxn=1e6+5;
int heap[maxn],n=0;//最小堆(下标从1开始) 
void deleteTop()//删除堆顶元素 
{
	pop_heap(heap+1,heap+1+n,greater<int>());
	n--;
}
void insert(int x)//插入元素 
{
	heap[++n]=x;
	push_heap(heap+1,heap+1+n,greater<int>());
}
int main()
{
	ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
	int t,a,b;
	cin>>t;
	while(t--)
	{
		cin>>a;
		if(a==1)
		{
			cin>>b;
			insert(b);
		}
		if(a==2)
			cout<<heap[1]<<endl;
		if(a==3)
			deleteTop();
	}
	return 0;
}

对于这道题,也可以直接用优先队列

#include <iostream>
#include <cstdio>
#include <queue>
using namespace std; 
int main()
{
	ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
	int t,a,b;
	priority_queue<int,vector<int>,greater<int>> q;
	cin>>t;
	while(t--)
	{
		cin>>a;
		if(a==1)
		{
			cin>>b;
			q.push(b);
		}
		if(a==2)
			cout<<q.top()<<endl;
		if(a==3)
			q.pop();
	}
	return 0;
}
  • 4
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

球王武磊

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值