[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); }
转载是允许的,但是除了博主同意的情况下,必须在文章的明显区域说明出处,否则将会追究其法律责任。