中位數 (優先佇列)
阿新 • • 發佈:2018-11-12
中位數
這種題型比較常見,所以總結下來為妙。
一般暴力的方法是找到排一個序,然後輸出中間點。
然後正解的方法是優先佇列。
解法
一個大根堆一個小根堆,用於儲存中位數左邊的數和中位數右邊的數。
然後每一次插入某個數的時候,可以插入到中間,然後判斷左右兩個堆的大小,保持均等即可。
#include <iostream> #include <queue> #include <cstring> #include <cstdio> #include <algorithm> #include <cmath> #include <vector> using namespace std; void read(int &x) { int f=1; x=0; char s=getchar(); while(s<'0'||s>'9') { if(s=='-') f=-1; s=getchar(); } while(s>='0'&&s<='9') { x=x*10+s-'0'; s=getchar(); } x*=f; } int n,m; int a[200000]; string mid="mid"; string add="add"; priority_queue<int,vector<int>,less<int> >B; priority_queue<int,vector<int>,greater<int> >S; int main() { read(n); for(int i=1; i<=n; i++) read(a[i]); sort(a+1,a+1+n); for(int i=1; i<=n/2; i++) B.push(a[i]); for(int i=n/2+1; i<=n; i++) S.push(a[i]); read(m); while(m--) { string s; cin >> s; if(s==add) { int opt; read(opt); if(opt>B.top()) S.push(opt); else if(opt<S.top()) B.push(opt); int tb=B.size(),ts=S.size(); while(tb-ts>=2) { int u=B.top(); B.pop(); S.push(u); tb=B.size(),ts=S.size(); } while(ts-tb>=2) { int u=S.top(); S.pop(); B.push(u); tb=B.size(),ts=S.size(); } } if(s==mid) { if(B.size()>=S.size()) printf("%d\n",B.top()); else printf("%d\n",S.top()); } } return 0; }