LUOGU1168
中位数
题目描述
给出一个长度为\(N\)的非负整数序列\(A_i\),对于所有\(1 ≤ k ≤ (N + 1) / 2\),输出\(A_1, A_1 \sim A_3, …,A_1 \sim A_{2k - 1}\)的中位数。即前\(1,3,5,…\)个数的中位数。
输入格式
第\(1\)行为一个正整数\(N\),表示了序列长度。
第\(2\)行包含\(N\)个非负整数\(A_i (A_i ≤ 10^9)\)。
输出格式
共\((N + 1) / 2\)行,第\(i\)行为\(A_1, A_3, …, A_{2k - 1}\)的中位数。
样例 #1
样例输入 #1
7
1 3 5 7 9 11 6
样例输出 #1
1
3
5
6
提示
对于\(20\%\)的数据,\(N ≤ 100\);
对于\(40\%\)的数据,\(N ≤ 3000\);
对于\(100\%\)的数据,\(N ≤ 100000\)。
对顶堆的经典应用。
对顶堆,就是建立两个堆,一个维护较大数的最小值,另一个维护较小数的最大值。通过堆的插入和弹出,使得两个堆等大(可以差1)来实时求出中位数。
#include<bits/stdc++.h>
using namespace std;
priority_queue<int>qd;//小数的最大
priority_queue<int ,vector<int>,greater<int> >qx;//大数的最小
int n;
int main()
{
scanf("%d",&n);
for(int x,i=1;i<=n;++i)
{
scanf("%d",&x);
if(qd.size()==qx.size())
{
if(qd.empty()||x<=qx.top())qd.push(x);
else
{
int y=qx.top();qd.push(y);qx.pop();
qx.push(x);
}
}
else
{
if(x>=qd.top())qx.push(x);
else
{
int y=qd.top();qx.push(y);qd.pop();
qd.push(x);
}
}
if(i&1)printf("%d\n",qd.top());
}
return 0;
}