1. 程式人生 > >堆模板(STL版)

堆模板(STL版)

題目描述

如題,初始小根堆為空,我們需要支援以下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

說明

時空限制:1000ms,128M

資料規模:

對於30%的資料:N<=15

對於70%的資料:N<=10000

對於100%的資料:N<=1000000(注意是6個0。。。不過不要害怕,經過編者實測,堆是可以AC的)

樣例說明:

故輸出為2、5

。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。--分割線

堆,這是個比較令人熟悉的容器

ta無非是維持一棵具有單調性的樹(從小到大 OR 從大到小)

所以它可以將一次搜尋的時雜變成O(log n);

具體看程式碼吧

這裡是stl的版本:(其實那後面那個手寫版本是有問題的,可我太弱,目前還沒調出來)

#include<bits/stdc++.h>
using namespace std;

//priority_queue<int> q 大根堆 
priority_queue<int, vector<int>, greater<int> > q;//小根堆 (<int>後要加‘ ’)
/*
q.top()//取得堆頂元素,並不會彈出
q.pop()//彈出堆頂元素
q.push()//往堆裡面插入一個元素
q.empty()//查詢堆是否為空,為空則返回1否則返回0
q.size()//查詢堆內元素數量
*/ int main(){ int n,x; cin>>n; while(n--){ int t; scanf("%d",&t); if(t==1){ scanf("%d",&x); q.push(x); } if(t==2){ printf("%d\n",q.top()); } if(t==3){ q.pop(); } } } /*情懷手寫版 int l;//大小 int dui[1000005]; void up_dui(int i,bool z){ if(i==1||z==0){return;} if(dui[i/2]>dui[i]) { swap(dui[i/2],dui[i]); } else { z=0; } up_dui(i/2,z); } void down_dui(int i){ if(i>=l) return; if(dui[i*2]<dui[i]){ swap(dui[i*2],dui[i]); down_dui(i*2); return; } if(dui[i*2+1]<dui[i]){ swap(dui[i*2+1],dui[i]); down_dui(i*2+1); return; } } void pushn(){ int x; scanf("%d",&x); ++l; dui[l]=x; up_dui(l,1); } void popn(){ printf("%d\n",dui[1]); } void deleten(){ dui[1]=dui[l]; dui[l]=0; --l; down_dui(1); } int main(){ cin>>n; while(n--){ int t; scanf("%d",&t); if(t==1){ pushn(); } if(t==2){ popn(); } if(t==3){ deleten(); } } } */

//跪求路過DALAO指導(QAQ)