洛谷 P3378 【模板】堆
阿新 • • 發佈:2018-06-01
什麽 als www har 操作 space return 有關 bit
題目地址:
$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) { inty=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); }
洛谷 P3378 【模板】堆