P1168 中位數 - 堆
阿新 • • 發佈:2018-11-02
對頂堆,維護第k大
考慮維護一個大根堆,一個小根堆。
這兩個堆總大小為當前區間長度,我們維護兩個性質:
1.小根堆總比大根堆多一個元素
2.小根堆所有元素都大於大根堆元素
這樣小根堆的堆頂就是區間中位數。
當需要加入一個新元素時,如果這個元素比小根堆堆頂要大,就加入小根堆中,反之則加入大根堆,這樣可以維護性質2
加入元素後,檢查兩個堆的大小關係,如果大小關係不滿足性質1,就在兩個堆之間搬運元素,由於加入規則的限制我們這樣搬來搬去仍然是符合性質2的
#include <algorithm> #include <iostream> #include <cstdio> #include <queue> using namespace std; #define debug(x) cerr << #x << "=" << x << endl; priority_queue <int, vector<int>, greater<int> > qmin; priority_queue <int> qmax; int n,a[100010]; int main() { cin >> n; for(int i=1; i<=n ;i++) { cin >> a[i]; if(qmin.empty()) { qmin.push(a[i]); cout << a[i] << endl; continue; } if(a[i] > qmin.top()) qmin.push(a[i]); else qmax.push(a[i]); while(qmax.size() > qmin.size()-1) { qmin.push(qmax.top()); qmax.pop(); } while(qmin.size() - 1 > qmax.size()) { qmax.push(qmin.top()); qmin.pop(); } if(i % 2) cout << qmin.top() << endl; } return 0; }