[POJ3784] [2009NewYork区域赛] Runnng Median [堆]

Link

光辉大复合神殿 . j p g \mathfrak{.jpg}

维护一个小顶堆一个大顶堆,每次插入跟小顶堆堆顶比较决定要放入哪个堆
放进去之后如果两个堆的大小相差超过 1 \mathfrak{1} 就进行调整
加上题目保证只在两堆大小和为奇数的时候进行查询,
这样保证了小顶堆里的数都不小于大顶堆里面的数,而且两堆最中间那个数是中位数。

双向链表也行;
当然也可以用大数据结构当区间 k k 大来做。

#include<cstdio>
#include<cstdlib>
#include<iostream>
#include<algorithm>
#include<cmath>
#include<queue>
#include<cstring>
#include<cctype>
#include<queue>
#include<vector>
using namespace std;
int P,N,M;
int Ai[10005]={};
priority_queue<int> QvQ;
priority_queue<int,vector<int>,greater<int> > QwQ;
void insert(const int&x)
{
	if(QwQ.empty()||QwQ.top()<x)QwQ.push(x);
	else QvQ.push(x);
	if(QwQ.size()>QvQ.size()+1)QvQ.push(QwQ.top()),QwQ.pop();
	if(QvQ.size()>QwQ.size()+1)QwQ.push(QvQ.top()),QvQ.pop();
}
int main()
{
	scanf("%d",&P);
	for(int cnm=1;cnm<=P;++cnm)
	{
		scanf("%d%d",&N,&M);
		printf("%d %d\n",N,M+1>>1);
		while(!QwQ.empty())QwQ.pop();
		while(!QvQ.empty())QvQ.pop();
		for(int pt=0,i=1;i<=M;++i)
		{
			scanf("%d",&Ai[i]);
			insert(Ai[i]);
			if(i&1)
			{
				if(QwQ.size()>QvQ.size())printf("%d ",QwQ.top());
				if(QvQ.size()>QwQ.size())printf("%d ",QvQ.top());
				if(++pt==10&&(i!=M))pt=0,putchar('\n');
			}
		}
		if(cnm<P)putchar('\n');
	}
    return 0;
}

猜你喜欢

转载自blog.csdn.net/Estia_/article/details/83178404