對頂堆學習筆記

2022-10-10 17:36:12 字數 1214 閱讀 9391

演算法思想:

一、問題:你需要維護乙個資料結構,支援以下操作:

1.插入乙個數

2.查詢當前資料結構中的中位數/第k小數(k為定值)

很多大佬應該一眼平衡樹了

平衡樹,不好寫!對頂堆,好寫!

二、做法

以查詢中位數為準

我們考慮維護乙個小根堆和乙個大根堆,如圖(「對頂」堆):

令大根堆為s1, 小根堆為s2

我們發現以圖中的結構,兩個堆內的資料恰好是從上到下遞增的

我們令兩個堆中的資料個數保持平衡,即:

①若$s1.size()>s2.size()+1$,將大根堆頂插入小根堆中

②若$s2.size()>s1.size()+1$,將小根堆頂插入大根堆中

進行插入操作時,將新數與大根堆堆頂比較,若小於大根堆堆頂則插入大根堆,否則插入小根堆

查詢操作時:

$若s1.size() < s2.size(),則中位數為s2.size()$

$若s1.size() > s2.size(),則中位數為s1.size()$

$若s1.size() == s2.size(),則中位數視題目要求而定$

(其實如果只是查詢第k小的話似乎不需要小根堆了)

例題:

sp15376 rmid - running median

用stl的優先佇列實現堆

#include #include #include #include using namespace std;

priority_queue q1, q2; //q1為大根堆, q2為小根堆

void insert(int s)

void print()

int main()

else if(s == -1) print();

else insert(s);

}return 0;

}

四倍經驗:sp16254 rmid2 - running median again

luogu p1168 中位數

luogu p3871 [tjoi2010]中位數

對頂堆學習筆記

處理動態中位數等問題,靈活運用了堆的性質,本質是維護兩個堆。大根堆 q 1 維護集合中較小值的部分的最大值。小根堆 q 2 維護集合中較大值的部分的最小值。注意到兩個堆中的元素各自是單調的,兩個堆間也是單調的。也就是說,q 1 中的任何乙個元素都不大於 q 2 中的任何乙個元素。那麼假設高度為權值,...

對頂堆的故事

總結 用大頂堆和小頂堆來實現,控制兩個堆的個數來實現將第幾個數暴露在兩個堆的中間,這樣就可以隨時輸出第幾個數,隨意以乙個頂堆的top 為標準,判斷下乙個數加在哪個堆裡,並時刻控制數量,這樣就可以將要求的第幾個數一直存疑兩個頂堆的top 之間。include include using namespa...

黑盒子 對頂堆

我們的大根堆中的所有數都必須小於小根堆中的數。而且還要注意,i每一次都是要增加1的,所以我們每次做完get操作後,都需要最小堆中的最小數彈出存入最大堆,也就是滿足第k小,因為k就是i,所以我們要這麼處理。倆個堆維護乙個有序序列,求第k個小的數 include include include incl...