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;
}

posted on 2022-07-27 15:20  gryzy  阅读(26)  评论(0编辑  收藏  举报

导航