演算法思想:
一、問題:你需要維護乙個資料結構,支援以下操作:
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;四倍經驗:sp16254 rmid2 - running median againpriority_queue q1, q2; //q1為大根堆, q2為小根堆
void insert(int s)
void print()
int main()
else if(s == -1) print();
else insert(s);
}return 0;
}
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...