標籤:vector queue 總結 namespace else 儲存 優先隊列 例題 class
中位元
這種題型比較常見,所以總結下來為妙。
一般暴力的方法是找到排一個序,然後輸出中間點。
然後正解的方法是優先隊列。
解法
一個大根堆一個小根堆,用於儲存中位元左邊的數和中位元右邊的數。
然後每一次插入某個數的時候,可以插入到中間,然後判斷左右兩個堆的大小,保持均等即可。
#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;}
例題
3871 中位元
中位元 (優先隊列)