ACwing 839 模擬堆(陣列模擬堆)

2021-10-09 06:42:40 字數 1783 閱讀 9478

維護乙個集合,初始時集合為空,支援如下幾種操作:

「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,表示操作次...