[Luogu3378] 【模板】堆 题解
题目地址:
$Luogu$:https://www.luogu.org/problemnew/show/P3378
那么我们一看到题目应该就会写这道题了吧。
我们需要支持三个操作:
1、插入一个数入小根堆。
2、输出小根堆的最小值。
3、删除小根堆的最小值。
由于我们知道,小根堆的最小值就是它的根,所以这题就很简单了。
你不用管什么$N<=10^6$,那些都没有关系。
第一个和第三个操作我们需要写两个函数来解决。第二个操作直接输出即可。
第一个函数:插入函数。
void insert(int x) { h[++l]=x; up(l); }
第二个函数:删除函数。
void _delete(int x) { h[x]=h[l--]; up(x); down(x); }
另附上浮操作$up$以及下沉操作$down$所用的函数。
void up(int x) { while(x>1&&h[x]<h[x>>1]) { swap(h[x], h[x>>1]); x>>=1; } }
void down(int x) { int y=x<<1; while(y<=l) { if(y+1<=l&&h[y+1]<h[y]) y++; if(h[y]<h[x]) { swap(h[x], h[y]); x=y, y=x<<1; } else break; } }
代码如下:
$code$
#include<bits/stdc++.h>
using namespace std;
const int maxN=1000000+1;
int h[maxN], n, l;
void read(int &), insert(int), up(int), down(int), _delete(int);
int main()
{
read(n);
for(int i=1; i<=n; i++)
{
int x;
read(x);
if(x==1)
{
int y;
read(y);
insert(y);
}
if(x==2) printf("%d\n", h[1]);
if(x==3) _delete(1);
}
return 0;
}
void read(int &x)
{
x=0;
char c=getchar();
while(c<'0'||c>'9') c=getchar();
while(c>='0'&&c<='9')
{
x=x*10+c-'0';
c=getchar();
}
}
void up(int x)
{
while(x>1&&h[x]<h[x>>1])
{
swap(h[x], h[x>>1]);
x>>=1;
}
}
void down(int x)
{
int y=x<<1;
while(y<=l)
{
if(y+1<=l&&h[y+1]<h[y]) y++;
if(h[y]<h[x])
{
swap(h[x], h[y]);
x=y, y=x<<1;
}
else break;
}
}
void insert(int x)
{
h[++l]=x;
up(l);
}
void _delete(int x)
{
h[x]=h[l--];
up(x);
down(x);
}
转载是允许的,但是除了博主同意的情况下,必须在文章的明显区域说明出处,否则将会追究其法律责任。

浙公网安备 33010602011771号