\(\\\)
處理動態中位數等問題,靈活運用了堆的性質,本質是維護兩個堆。
大根堆\(q_1\):維護集合中較小值的部分的最大值。
小根堆\(q_2\):維護集合中較大值的部分的最小值。
注意到兩個堆中的元素各自是單調的,兩個堆間也是單調的。也就是說,\(q_1\)中的任何乙個元素都不大於\(q_2\)中的任何乙個元素。
那麼假設高度為權值,兩個堆可以形象化的表示成:
如果兩個堆的大小相差不超過\(1\),較大的那個堆的堆頂必定是中位數(偶數個數時中位數是排序後中間的兩個之一)
\(upd:\) 圖中的 \(q1\) 和 \(q2\) 標反了,權值是越高越大。
\(\\\)
\(\\\)
對乙個集合一共有\(n\)次操作,計數器\(cnt\)初始為\(0\):\(\\\)
動態\(k\)小值,注意題目限制的\(q_2\)大小是變化的,每次詢問後記得調整好。
\(\\\)
#include#include#include#include#include#include#include#include#define n 200010
#define r register
#define gc getchar
using namespace std;
inline int rd()
while(isdigit(c))
return f?-x:x;
}int n,m,cnt,x,a[n];
priority_queueq1,q2;
int main()
}return 0;
}
對頂堆學習筆記
演算法思想 一 問題 你需要維護乙個資料結構,支援以下操作 1.插入乙個數 2.查詢當前資料結構中的中位數 第k小數 k為定值 很多大佬應該一眼平衡樹了 平衡樹,不好寫!對頂堆,好寫!二 做法 以查詢中位數為準 我們考慮維護乙個小根堆和乙個大根堆,如圖 對頂 堆 令大根堆為s1,小根堆為s2 我們發...
對頂堆的故事
總結 用大頂堆和小頂堆來實現,控制兩個堆的個數來實現將第幾個數暴露在兩個堆的中間,這樣就可以隨時輸出第幾個數,隨意以乙個頂堆的top 為標準,判斷下乙個數加在哪個堆裡,並時刻控制數量,這樣就可以將要求的第幾個數一直存疑兩個頂堆的top 之間。include include using namespa...
黑盒子 對頂堆
我們的大根堆中的所有數都必須小於小根堆中的數。而且還要注意,i每一次都是要增加1的,所以我們每次做完get操作後,都需要最小堆中的最小數彈出存入最大堆,也就是滿足第k小,因為k就是i,所以我們要這麼處理。倆個堆維護乙個有序序列,求第k個小的數 include include include incl...