維護乙個集合,初始時集合為空,支援如下幾種操作:
「i x」,插入乙個數x;
「pm」,輸出當前集合中的最小值;
「dm」,刪除當前集合中的最小值(資料保證此時的最小值唯一);
「d k」,刪除第k個插入的數;
「c k x」,修改第k個插入的數,將其變為x;
現在要進行n次操作,對於所有第2個操作,輸出當前集合的最小值。
輸入格式
第一行包含整數n。
接下來n行,每行包含乙個操作指令,操作指令為」i x」,」pm」,」dm」,」d k」或」c k x」中的一種。
輸出格式
對於每個輸出指令「pm」,輸出乙個結果,表示當前集合中的最小值。
每個結果佔一行。
資料範圍
1≤n≤105
−109≤x≤109
資料保證合法。
輸入樣例:
8i -10
pmi -10
d 1c 2 8
i 6pm
dm輸出樣例:
-106
如題,要求完成堆的各種操作。
要求完成堆的種種操作,但是我們發現最後兩個操作靠優先佇列priority_queue是不能實現的,因為要對堆中任意乙個數進行操作,所以要用陣列模擬堆,為了能訪問堆中的任意乙個數,需要額外開兩個對映陣列:
這兩個對映關係是呈反函式的,ph[i] = j, ph[j] = i, 如果想訪問第k個插入堆中的數,則ph[k] 存的值就是第k個插入的數在堆中的下標。我們知道堆中的操作是要不斷交換兩個數的,因為用到了對映陣列,所以要定義一下交換函式,a, b均為堆中的下標,交換函式:
void
heap_swap
(int a,
int b)
堆中交換兩個數,那麼他們的對映關係也應該變化,ph[i] 意為陣列下標 i 在堆中的位置,那麼我們知道堆我們知道堆中的位置,就可以通過hp[a] 來對映出 i 在陣列中的位置從而完成交換。
關於修改操作,將第k個數修改,先對映一下k在堆中的位置,ph[k] 得到第k個數在堆中的下標,將其修改為 x ,然後如何判斷down還是up,很簡單,關於堆中的任意乙個元素,down 和 up 操作最多執行一次,所以都來一次就可以,一定有乙個是不執行的。
#include
#include
#include
using
namespace std;
const
int n =
1e5+50;
int h[n]
, ph[n]
, hp[n]
, idx =
0, tot =0;
void
hswap
(int a,
int b)
void
down
(int u)
}voidup(
int u)
}int
main()
elseif(
!strcmp
(op,
"pm"))
printf
("%d\n"
, h[1]
);//輸出堆頂
elseif(
!strcmp
(op,
"dm"))
elseif(
!strcmp
(op,
"d")
)else
}return0;
}
AcWing 839 模擬堆(C 演算法)
1 題目 維護乙個集合,初始時集合為空,支援如下幾種操作 i x 插入乙個數x pm 輸出當前集合中的最小值 dm 刪除當前集合中的最小值 資料保證此時的最小值唯一 d k 刪除第k個插入的數 c k x 修改第k個插入的數,將其變為x 現在要進行n次操作,對於所有第2個操作,輸出當前集合的最小值。...
AcWing 模擬棧 棧 模擬
時 空限制 1s 64mb 實現乙個棧,棧初始為空,支援四種操作 1 push x 向棧頂插入乙個數x 2 pop 從棧頂彈出乙個數 3 empty 判斷棧是否為空 4 query 查詢棧頂元素。現在要對棧進行m個操作,其中的每個操作3和操作4都要輸出相應的結果。第一行包含整數m,表示操作次數。接下...
AcWing 模擬佇列 佇列 模擬
時 空限制 1s 64mb 實現乙個佇列,佇列初始為空,支援四種操作 1 push x 向隊尾插入乙個數x 2 pop 從隊頭彈出乙個數 3 empty 判斷佇列是否為空 4 query 查詢隊頭元素。現在要對佇列進行m個操作,其中的每個操作3和操作4都要輸出相應的結果。第一行包含整數m,表示操作次...