poj3784(对顶堆)
题意:多组数据,让你求出1~i(i为奇数&&i<=n)的中位数
思路:首先复杂度必为O(n)或O(nlogn)的(数据范围)
思索,如果题目要求1次中位数,好求!排个序,取a[(n+1)/2]就好了 [这道题n的前提是奇数哈]
可是???要求多次中位数,而且是每次加入两个数后,再求一次?
别慌!!!已知中位数的性质是跟数值的顺序有关的。
顺序?大家想一想有哪个数据结构能够动态维护数列顺序,并1次操作复杂度在O(logn)之内
那当然是堆【肯定用优先队列啦】^_^
方式:【对顶堆】
不要太在乎为何叫“对顶堆”,因为我也不知道
通过取中间的数,可以想到维护两个堆:一个大根堆(叫她Qx),一个小根堆(叫他Qn),这两个堆的大小无论怎样动态变化都恒保持:Qx.size()-Qn.size()=1或0 [Qx.size()总是>=Qn.size()的]
要两个堆的目的大家肯定都能想到了,因为一旦i为奇数要输出时,直接输出Qx.top()就好了。不过这只是脑补出了一些过程,请看下面:

我说的有点啰嗦,大家还是看看代码吧:
#include<stdio.h>
#include<algorithm>
#include<queue>
using namespace std;
priority_queue<int> Qx;
priority_queue<int,vector<int>,greater<int> > Qn;
int main() {
// freopen("poj3785.out","w",stdout);
int t;
scanf("%d",&t);
while(t--) {
while(!Qn.empty()) Qn.pop();
while(!Qx.empty()) Qx.pop();
int p,n; scanf("%d%d",&p,&n);
printf("%d %d\n",p,(n+1)/2);
for(int i=1;i<=n;i++) {
int b; scanf("%d",&b);
//之所以要加上特判,因为要保证两个队列都非空,才能不运行错误
if(i==1) {
Qx.push(b); printf("%d ",b);
}
else if(i==2) {
if(b<Qx.top()) Qn.push(Qx.top()),Qx.pop(),Qx.push(b);
else Qn.push(b);
}
else if(Qx.size()==Qn.size()) { //Qx.size()必须+1
if(b<=Qn.top()) Qx.push(b);
else { //b>Qn.top()
Qx.push(Qn.top()); Qn.pop(); Qn.push(b); //将小根堆的堆头插入大根堆,并将b插入小根堆
}
printf("%d ",Qx.top());
if(((i+1)/2)%10==0) printf("\n");
}
else { //Qn.size()必须+1
if(b>=Qx.top()) Qn.push(b);
else { //b<Qx.top();
Qn.push(Qx.top()); Qx.pop(); Qx.push(b); //有没有觉得是15行的反操作呢?
}
}
}
if((n+1)/2%10!=0) printf("\n");
}
return 0;
}
有什么建议,欢迎讨论
poj3784(对顶堆)的更多相关文章
- poj3784 Running Median[对顶堆]
由于我不会讲对顶堆,所以这里直接传上一个巨佬的学习笔记. 对顶堆其实还是很容易理解的,想这题的时候自己猜做法也能把没学过的对顶堆给想出来.后来了解,对顶堆主要还是动态的在线维护集合$K$大值.当然也可 ...
- hdu3282 链表或者对顶堆
维护序列的动态中位数 第一次用链表做题..感觉指针指来指去也挺麻烦的.. 本题链表解法就是用数组模拟出一个链表,然后离线输入所有数,排序,按照输入顺序在链表里删除元素,一次性删掉两个,然后中位数指针对 ...
- 【uoj#280】[UTR #2]题目难度提升 对顶堆+STL-set
题目描述 给出 $n$ 个数 $a_1,a_2,...,a_n$ ,将其排为序列 $\{p_i\}$ ,满足 $\{前\ i\ 个数的中位数\}$ 单调不降.求字典序最大的 $\{p_i\}$ . 其 ...
- hdu4261 Estimation[暴力dp+对顶堆]
https://vjudge.net/problem/HDU-4261 对于一个长2000的数列划分最多25个块,每块代价为块内每个数与块内中位数差的绝对值之和,求最小总代价. 套路化地,设$f[i] ...
- 【POJ 3784】 Running Median (对顶堆)
Running Median Description For this problem, you will write a program that reads in a sequence of 32 ...
- P1168 中位数(对顶堆)
题意:维护一个序列,两种操作 1.插入一个数 2.输出中位数(若长度为偶数,输出中间两个较小的那个) 对顶堆 维护一个小根堆,一个大根堆,大根堆存1--mid,小根堆存mid+1---n 这样堆顶必有 ...
- 洛谷 - P1801 - 黑匣子 - 对顶堆
这道题是提高+省选-的难度,做出来的话对数据结构题目的理解会增加很多. 可以使用一种叫做对顶堆的东西,对顶堆是在线维护第n小的logn的算法.大概的思路是,假如我们要找的是第n小,我们就维护一个大小为 ...
- bzoj 1112: [POI2008]砖块Klo【对顶堆】
priority_queue实现的对顶堆,细节超级多WA了十几次--但是理论上是最简便的orz其实是我已经不会写平衡树了 枚举左端点,显然要把这一段的高度搞成(l,l+k-1)的高度中位数,所以需要一 ...
- 【Luogu P1168】【Luogu P1801&UVA 501】中位数&黑匣子(Black Box)——对顶堆相关
Luogu P1168 Luogu P1801 UVA 501(洛谷Remote Judge) 前置知识:堆.优先队列STL的使用 对顶堆 是一种在线维护第\(k\)小的算法. 其实就是开两个堆,一个 ...
随机推荐
- 讲清楚之 javascript中的this
讲清楚之 javascript中的this 这一节来探讨this. 在 javascript 中 this 也是一个神的存在,相对于 java 等语言在编译阶段确定,而在 javascript 中, ...
- java中求一下2008年5月31日, 往前倒30天是哪天?
题目9: 2008年5月31日, 往前倒30天是哪天? import java.util.*; public class Test { public static void main(Str ...
- web.xml的作用及基本配置
web工程中的web.xml文件有什么作用呢?它是每个web.xml工程都必须的吗? 一个web中完全可以没有web.xml文件,也就是说,web.xml文件并不是web工程必须的.那什么时候需要,什 ...
- ajax自己封装
function paramsSeralize(obj){ if(!obj || typeof !== 'object') return obj; let res = ''; for (const k ...
- oracle三个重要参数文件:pfile和spfile和init.ora
Oracle中的参数文件是一个包含一系列参数以及参数对应值的操作系统文件.它们是在数据库实例启动第一个阶段时候加载的, 决定了数据库的物理 结构.内存.数据库的限制及系统大量的默认值.数据库的各种物理 ...
- 线程的概念及Thread模块的使用
线程 一.什么是线程? 我们可以把进程理解成一个资源空间,真正被CPU执行的就是进程里的线程. 一个进程中最少会有一条线程,同一进程下的每个线程之间资源是共享的. 二.开设线程的两种方式 开设进程需要 ...
- 【2021 ICPC Asia Jinan 区域赛】 C Optimal Strategy推公式-组合数-逆元快速幂
题目链接 题目详情 (pintia.cn) 题目 题意 有n个物品在他们面前,编号从1自n.两人轮流移走物品.在移动中,玩家选择未被拿走的物品并将其拿走.当所有物品被拿走时,游戏就结束了.任何一个玩家 ...
- CoAP调试工具Mozi.IoT.CoAP应用详解
前言 CoAP是一种类HTTP协议的物联网专用协议,其数据包为人类不可阅读的字节流形式,在开发相关应用的时候往往不能准确的了解数据包的内容.故需要专用的调试工具对数据和通讯进行调试.这篇文章是为了让开 ...
- Azure DevOps (十一) 通过Azure Devops部署一个.NET Core WebAPI
前几篇文章中,我们讨论了如何通过流水线实现项目的编译.上传.打包.部署等操作,今天我们来实现一套完整的流程,把之前碎片化的知识点给串起来. 本次我们使用一个ASP.NET Core的WebApi项目来 ...
- CTO 说了,如果发现谁用 kill -9 关闭程序就开除
关注「开源Linux」,选择"设为星标" 回复「学习」,有我为您特别筛选的学习资料~ 来源:blog.csdn.net/qq_33220089 正文 kil ...