AcWing 106 動態中位數 (對頂堆)
阿新 • • 發佈:2020-11-04
https://www.acwing.com/problem/content/108/
維護一個大根堆,一個小根堆,設當前序列長度為\(M\)
當前序列從小到大排名\(1~M/2\)的整數存在大根堆
排名\(M/2+1~M\)的整數存在小根堆,
如果插入後某一堆元素過多,就把該堆堆頂取出來插入令一個堆,
這樣序列的中位數就是小根堆的堆頂
#include<cstdio> #include<cstring> #include<algorithm> #include<iostream> #include<cmath> #include<stack> #include<queue> using namespace std; typedef long long ll; const int maxn = 100010; int T, n, Case, cnt; int ans[maxn]; priority_queue<int> qma; priority_queue<int, vector<int>, greater<int> > qmi; ll read(){ ll s=0,f=1; char ch=getchar(); while(ch<'0' || ch>'9'){ if(ch=='-') f=-1; ch=getchar(); } while(ch>='0' && ch<='9'){ s=s*10+ch-'0'; ch=getchar(); } return s*f; } int main(){ T = read(); while(T--){ while(!qma.empty()) qma.pop(); while(!qmi.empty()) qmi.pop(); cnt = 0; Case = read(), n = read(); int x; for(int i=1;i<=n;++i){ x = read(); if(i==1) qmi.push(x); else{ if(x < qmi.top()) qma.push(x); else qmi.push(x); } while(qma.size() > (i/2)){ int tmp = qma.top(); qmi.push(tmp); qma.pop(); } int S; if(i%2 == 1) S = i/2 + 1; else S = i/2; while(qmi.size() > S){ int tmp = qmi.top(); qma.push(tmp); qmi.pop(); } if(i%2 == 1) ans[++cnt] = qmi.top(); } printf("%d %d\n",Case,cnt); int tot = 0; for(int i=1;i<=cnt;++i){ if(tot == 10){ printf("\n"); tot = 0; } printf("%d ",ans[i]); ++tot; }printf("\n"); } return 0; }