Luogu3378 【手写堆模板】

题目描述

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

  1. 给定一个整数 xx,请将 xx 加入到数列中。
  2. 输出数列中最小的数。
  3. 删除数列中最小的数(如果有多个数最小,只删除 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 15n15。
  • 对于 70\%70% 的数据,保证 n \leq 10^4n104。
  • 对于 100\%100% 的数据,保证 1 \leq n \leq 10^61n106,1 \leq x \lt 2^{31}1x<231,op \in \{1, 2, 3\}op{1,2,3}。

 

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <algorithm>
 4 #include <cstring>
 5 #include <string>
 6 using namespace std;
 7 
 8 const int N = 1000001;
 9 int heap[N], n, ans;
10 int tot;
11 
12 void down(int k){
13     int l = k*2;
14     int r = k*2 + 1;
15     if(l > tot) return;
16     if(heap[l] < heap[k] || heap[r] < heap[k]){
17         if(heap[l] < heap[r]){
18             swap(heap[l], heap[k]);
19             down(l);
20         }else{
21             swap(heap[r], heap[k]);
22             down(r);
23         }
24     }
25 }
26 
27 void up(int k){
28     if(k == 1)
29         return;
30     if(heap[k] < heap[k>>1]){
31         swap(heap[k], heap[k>>1]);
32         up(k>>1);
33     }
34 }
35 
36 void push(int x){
37     heap[++tot] = x;
38     up(tot);
39 }
40 
41 int pop(){
42     int x = heap[1];
43     heap[1] = heap[tot--];
44     down(1);
45     return x;
46 }
47 
48 int main(){
49     memset(heap, 127, sizeof(heap));
50     scanf("%d", &n);
51     for(int i=1;i<=n;i++){
52         int x;
53         scanf("%d", &x);
54         if(x == 1){
55             int tmp;
56             scanf("%d", &tmp);
57             push(tmp);
58         }
59         if(x == 2){
60             printf("%d\n", heap[1]);
61         }
62         if(x == 3){
63             pop();
64         }
65             
66     }
67     
68     return 0;
69 }

 

posted @ 2021-03-05 20:43  sinEagle  阅读(61)  评论(0编辑  收藏  举报