首页 > 代码库 > 堆的模板题【洛谷P3378】

堆的模板题【洛谷P3378】

题目描述

如题,初始小根堆为空,我们需要支持以下3种操作:

操作1: 1 x 表示将x插入到堆中

操作2: 2 输出该小根堆内的最小数

操作3: 3 删除该小根堆内的最小数

输入输出格式

输入格式:

第一行包含一个整数N,表示操作的个数

接下来N行,每行包含1个或2个正整数,表示三种操作,格式如下:

操作1: 1 x

操作2: 2

操作3: 3

输出格式:

包含若干行正整数,每行依次对应一个操作2的结果。

输入样例#1:
5
1 2
1 5
2
3
2
输出样例#1:
2
5

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 int c[1000010];//注意数组的大小 
 4 int n;
 5 int num=0;
 6 
 7 void Swap(int i,int j)//Swap函数注意大写,否则有可能与库函数冲突 
 8 {
 9    int t=c[i];
10    c[i]=c[j];
11    c[j]=t;
12 }
13 
14 void siftdown(int k)
15 {
16    int t,flag=0;
17    while(k*2<=num&&flag==0)
18    {
19       if(c[k]>c[k*2])
20          t=k*2;
21       else t=k;//标记!!! 
22       if(k*2+1<=num)
23       {
24           if(c[t]>c[k*2+1])
25              t=k*2+1;//标记!!! 
26       }
27       if(t!=k)
28        { Swap(t,k);k=t;}//标记!!! 
29       else  flag=1;
30    }
31    return ;
32 }
33 
34 void siftup(int k)
35 {
36    int flag=0;
37      while(k!=1&&flag==0)
38      {
39          if(c[k]<c[k/2])
40              Swap(k,k/2);
41         else flag=1;
42         k=k/2;//标记!!! 
43      }
44      return ;
45 }
46 
47 int main()
48 {
49    ios::sync_with_stdio(false);//读入虐我千百遍…… 
50    cin>>n;
51    int t1,t2;
52    while(n--)
53    {
54       cin>>t1;
55       if(t1==1)
56       {
57          cin>>t2;
58          num++;
59          c[num]=t2;
60          siftup(num);
61          continue;
62       }
63       if(t1==2)
64         { cout<<c[1]<<endl;continue;}
65       if(t1==3)
66       {
67          c[1]=c[num];
68          num--;siftdown(1);
69          continue;
70      }
71    }
72    return 0;
73 }

 

堆的模板题【洛谷P3378】