中位数 对顶堆

题目描述

给出一个长度为NNN的非负整数序列AiA_iAi?,对于所有1≤k≤(N+1)/21 ≤ k ≤ (N + 1) / 21≤k≤(N+1)/2,输出A1,A3,…,A2k?1A_1, A_3, …, A_{2k - 1}A1?,A3?,…,A2k?1?的中位数。即前1,3,5,…1,3,5,…1,3,5,…个数的中位数。

输入输出格式

输入格式:

第111行为一个正整数NNN,表示了序列长度。

第222行包含NNN个非负整数Ai(Ai≤109)A_i (A_i ≤ 10^9)Ai?(Ai?≤109)。

输出格式:

共(N+1)/2(N + 1) / 2(N+1)/2行,第iii行为A1,A3,…,A2k?1A_1, A_3, …, A_{2k - 1}A1?,A3?,…,A2k?1?的中位数。

输入输出样例

输入样例#1:
复制

7
1 3 5 7 9 11 6

输出样例#1: 复制

1
3
5
6

说明

对于20%20\%20%的数据,N≤100N ≤ 100N≤100;

对于40%40\%40%的数据,N≤3000N ≤ 3000N≤3000;

对于100%100\%100%的数

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstdlib>
#include<cstring>
#include<string>
#include<cmath>
#include<map>
#include<set>
#include<vector>
#include<queue>
#include<bitset>
#include<ctime>
#include<deque>
#include<stack>
#include<functional>
#include<sstream>
//#include<cctype>
//#pragma GCC optimize(2)
using namespace std;
#define maxn 700005
#define inf 0x7fffffff
//#define INF 1e18
#define rdint(x) scanf("%d",&x)
#define rdllt(x) scanf("%lld",&x)
#define rdult(x) scanf("%lu",&x)
#define rdlf(x) scanf("%lf",&x)
#define rdstr(x) scanf("%s",x)
typedef long long  ll;
typedef unsigned long long ull;
typedef unsigned int U;
#define ms(x) memset((x),0,sizeof(x))
const long long int mod = 1e9 + 7;
#define Mod 1000000000
#define sq(x) (x)*(x)
#define eps 1e-3
typedef pair<int, int> pii;
#define pi acos(-1.0)
//const int N = 1005;
#define REP(i,n) for(int i=0;i<(n);i++)
typedef pair<int, int> pii;
inline ll rd() {
	ll x = 0;
	char c = getchar();
	bool f = false;
	while (!isdigit(c)) {
		if (c == ‘-‘) f = true;
		c = getchar();
	}
	while (isdigit(c)) {
		x = (x << 1) + (x << 3) + (c ^ 48);
		c = getchar();
	}
	return f ? -x : x;
}

ll gcd(ll a, ll b) {
	return b == 0 ? a : gcd(b, a%b);
}
int sqr(int x) { return x * x; }

/*ll ans;
ll exgcd(ll a, ll b, ll &x, ll &y) {
	if (!b) {
		x = 1; y = 0; return a;
	}
	ans = exgcd(b, a%b, x, y);
	ll t = x; x = y; y = t - a / b * y;
	return ans;
}
*/

int n;
priority_queue<int, vector<int> >q1;
priority_queue<int, vector<int>, greater<int> >q2;

int main() {
	//ios::sync_with_stdio(0);
	rdint(n);
	int x; rdint(x); q1.push(x); cout << x << endl;
	for (int i = 2; i <= n; i++) {
		rdint(x);
		if (x > q1.top())q2.push(x);
		else q1.push(x);
		while (abs((int)q1.size() - (int)q2.size()) > 1) {
			if ((int)q1.size() > (int)q2.size()) {
				q2.push(q1.top()); q1.pop();
			}
			else {
				q1.push(q2.top()); q2.pop();
			}
		}
		if (i % 2) {
			if ((int)q1.size() > (int)q2.size()) {
				cout << q1.top() << endl;
			}
			else {
				cout << q2.top() << endl;
			}
		}
	}
	return 0;
}

据,N≤100000N ≤ 100000N≤100000。

原文地址:https://www.cnblogs.com/zxyqzy/p/10262077.html

时间: 2024-10-31 12:40:52

中位数 对顶堆的相关文章

P1168 中位数(对顶堆)

题意:维护一个序列,两种操作 1.插入一个数 2.输出中位数(若长度为偶数,输出中间两个较小的那个) 对顶堆 维护一个小根堆,一个大根堆,大根堆存1--mid,小根堆存mid+1---n 这样对顶必有中位数. 每次操作后维护两个堆元素数量,保证一个比另一个多1或相等 #include<cstdio> #include<iostream> #include<algorithm> #include<queue> using namespace std; #def

poj 3784(对顶堆)

Running Median Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 1824   Accepted: 889 Description For this problem, you will write a program that reads in a sequence of 32-bit signed integers. After each odd-indexed value is read, output t

浅谈对顶堆

对顶堆详解 我们知道,堆是一种极有用的数据结构.它能在短时间内将数据维护成单调递增/递减的序列.但是这种"朴素堆"对于问题求解起到的效果毕竟是有限的.所以我们在朴素堆的基础上,进行深入思考和适当变形,使之能解决一些其他的用朴素堆解决不了的问题,并使思路变得简洁有效. 这篇随笔就堆中的一个分支--对顶堆进行讲解,读者在阅读前应该掌握堆的基本概念,以便于更好地理解对顶堆. 如果把堆中的大根堆想成一个上宽下窄的三角形,把小根堆想成一个上窄下宽的三角形,那么对顶堆就可以具体地被想象成一个&qu

黑匣子 对顶堆

黑匣子 对顶堆 对顶堆,由一个小跟堆和一个大根堆组成,且满足小跟堆堆顶大于大根堆堆顶. ------- ----- <-- 小跟堆 --- - - --- ----- <-- 大根堆 ------- 可以看出对顶堆满足从上自下一直递减的性质 黑匣子_NOI导刊2010提高 题面 而这道题要维护第\(i\)小,即是让我们维护一个对顶堆,使大根堆大小为\(i-1\),小跟堆的堆顶即是第\(i\)小. #include <cstdio> #include <queue> #d

黑匣子(对顶堆

# 题意在最开始,黑盒子是空的,并且i=0.现在对黑盒子进行一系列的操作处理,操作包括以下两种:1.ADD(x):表示将x加入到黑盒子中.2.GET:使i增加1,输出黑盒子中第i小的数值(即将所有数按升序排序后的第i个数).下面给出一个具体例子: 为了方便描述,下面我们定义两个序列:1.A表示:这个序列由加入到黑盒子内的所有元素按加入顺序排列后得到,上例中的A序列为(3,1,-4,2,8,-1000,2).2.u(1),u(2),…,u(N): 这个序列的第i项表示的是第i次GET操作时,盒子内

64 - 数据流中的中位数 || STL 堆

题目: 如何得到一个数据流中的中位数?如果从数据流中读出奇数个数值,那么中位数就是所有数值排序之后位于中间的数值.如果从数据流中读出偶数个数值,那么中位数就是所有数值排序之后中间两个数的平均值. 思路解析 数据是从数据流读出,因此数组的个数是再逐渐的增加.如何选用一个容器,能够存储数据,并能够给出中位数. 无序数组:插入O(1) partation操作找出中位数 O(n) 有序数组:插入O(n) 找出中位数O(1) 有序链表:插入O(n) 找出中位数O(1) 搜索二叉树:插入O(logn)~O(

Running Median POJ - 3784 (对顶堆/优先队列)

For this problem, you will write a program that reads in a sequence of 32-bit signed integers. After each odd-indexed value is read, output the median (middle value) of the elements received so far. Input The first line of input contains a single int

[剑指offer] 41. 数据流中的中位数 (大小堆,优先队列)

对于海量数据与数据流,用最大堆,最小堆来管理. class Solution { public: /* * 1.定义一个规则:保证左边(大顶堆)和右边(小顶堆)个数相差不大于1,且大顶堆的数值都小于等于小顶堆的数 * 2.大小堆顶可以用优先序列实现 插入规则: 当插入数值小于左边的堆顶时候,就插入左边,否则插入右边堆.(注意初始为空时,插入不能比较) 调整使得满足个数差<=1: 正常时是只有两种情况:p=q或者p=q+1,由于每插一个值就会考虑调整,那么边界情况就是p=q+2或者p+1=q p=

10/16 对顶堆算法研究(POJ 3784)

/* 考虑维护两个堆 一个堆是大根堆,存储1-x的元素 一个堆是小根堆,存储x+1-N的元素 对于一个加入的元素y,考虑将其加入大根堆or小根堆? 如果y>mid,那么将其加入小根堆(上面的堆) 如果y<mid,那么将其加入大根堆(下面的堆) 并且在每一次操作之后维护堆的状态是合法的! 也就是维护堆得大小正确 */#include<cstdio>#include<algorithm>#include<cstring>#include<queue>