【模板】堆
【模板】堆
题目描述
给定一个数列,初始为空,请支持下面三种操作:
1.给定一个整数
2.输出数列中最小的数。
3.删除数列中最小的数(如果有多个数最小,只删除
输入格式
第一行是一个整数,表示操作的次数
接下来
- 若
,则后面有一个整数 ,表示要将 加入数列。 - 若
,则表示要求输出数列中的最小数。 - 若
,则表示删除数列中的最小数。如果有多个数最小,只删除 个。
输出格式
对于每个操作
样例 #1
样例输入 #1
5
1 2
1 5
2
3
2
样例输出 #1
2
5
提示
【数据规模与约定】
- 对于
的数据,保证 。 - 对于
的数据,保证 。 - 对于
的数据,保证 , , 。
题解
好困,ac了就去睡觉了
#include <iostream>
#include<algorithm>
using namespace std;
const int M =10e6+10;
//val[i]表示第i个元素,sz表示堆的大小
int val[M], sz;
void push(int x);
int top();
void pop();
void heap_swap(int x, int y);
void up(int u);
void down(int u);
int main() {
int n;cin >> n;
while (n--)
{
int op, num;
cin >> op;
switch (op)
{
case 1://插入
cin >> num;
push(num);
break;
case 2://取出
cout<< top() << endl;
break;
case 3://删除
pop();
break;
}
}
return 0;
}
void push(int x) {
sz++;
val[sz] = x;
up(sz);
}
int top() {
return val[1];
}
void pop() {
heap_swap(1, sz);
sz--;
down(1);
}
//交换两个数的值
void heap_swap(int x, int y){
swap(val[x], val[y]);
}
//上浮小节点
void up(int u) {
while (u / 2 && val[u / 2] > val[u]) {
heap_swap(u, u / 2);
u /= 2;
}
}
//下沉节点
void down(int u) {
//用p跟踪
int p = u;
if (u * 2 <= sz && val[u * 2] < val[p])p = u * 2;
if (u * 2 + 1 <= sz && val[u * 2 + 1] < val[p])p = u * 2 + 1;
if (p != u) {
heap_swap(u, p);
down(p);
}
}