洛谷P3378 【模板】堆
给定一个数列,初始为空,请支持下面三种操作:
给定一个整数 xx,请将 xx 加入到数列中。
输出数列中最小的数。
删除数列中最小的数(如果有多个数最小,只删除 11 个)。
输入格式
第一行是一个整数,表示操作的次数 nn。
接下来 nn 行,每行表示一次操作。每行首先有一个整数 opop 表示操作类型。
若 op = 1op=1,则后面有一个整数 xx,表示要将 xx 加入数列。
若 op = 2op=2,则表示要求输出数列中的最小数。
若 op = 3op=3,则表示删除数列中的最小数。如果有多个数最小,只删除 11 个。
输出格式
对于每个操作 22,输出一行一个整数表示答案。
输入输出样例
输入 #1复制
5
1 2
1 5
2
3
2
输出 #1复制
2
5
说明/提示
数据规模与约定
对于 30%30% 的数据,保证 n \leq 15n≤15。
对于 70%70% 的数据,保证 n \leq 10^4n≤10
4
。
对于 100%100% 的数据,保证 1 \leq n \leq 10^61≤n≤10
6
,1 \leq x \lt 2^{31}1≤x<2
31
,op \in {1, 2, 3}op∈{1,2,3}。
#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
#define inf 0x3f3f3f3f
int a[1000005];
int ida;
void put(int k)
{
a[++ida] = k;
int n = ida;
while(n > 1){
int fa = n>>1;
if(a[fa] < a[n]) break;
swap(a[fa],a[n]);
n = fa;
}
}
void del()
{
int now = 1;
a[1] = a[ida--];
while(2*now <= ida )
{
int next = 2*now;
if(next < ida&&a[next] > a[next+1]) next++;
if(a[next] > a[now]) break;
swap(a[next],a[now]);
now = next;
}
}
int main()
{ int n,op,k;
cin>>n;
ida = 0;
for(int i = 1;i <= n;i++){
cin>>op;
if(op == 1) {
cin>>k;
put(k);
}
else if(op == 2){
cout<<a[1]<<endl;
}
else if(op == 3){
del();
}
}
return 0;
}