poj3784 Running Median[对顶堆]】的更多相关文章

由于我不会讲对顶堆,所以这里直接传上一个巨佬的学习笔记. 对顶堆其实还是很容易理解的,想这题的时候自己猜做法也能把没学过的对顶堆给想出来.后来了解,对顶堆主要还是动态的在线维护集合$K$大值.当然也可以带删除.但是可能退化,具体见另外一个题的说明. 像这题维护中位数就是要求第$N/2+1$大的数,所以可以让大根堆维护前$n/2$项,小根堆维护后$n/2+1$项(这里指排好序的).然后每次插入的时候及时调整即可,由于调整幅度不大,所以可以保证复杂度是$log$级别的. 代码被我写繁了因为我当时还不…
Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 1670   Accepted: 823 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 the median (midd…
Running Median 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 the median (middle value) of the elements received so far. Input The first line of…
Running Median Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 3406   Accepted: 1576 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…
浅谈堆:https://www.cnblogs.com/AKMer/p/10284629.html 题目传送门:http://poj.org/problem?id=3784 用一个"对顶堆"动态维护中位数. 一个大根堆维护前半部分的权值,一个小根堆维护后半部分的权值. 新进来一个数如果小于大根对的权值就加进大根对,否则就加进小根堆. 每次动态维护大小,使得大根堆的大小为数字的一半. 大根对的堆顶就是中位数. 为了方便我把大根堆里的数取了个反也就变小根堆了. 时间复杂度:\(O(Tnlo…
题意:多组数据,让你求出1~i(i为奇数&&i<=n)的中位数 思路:首先复杂度必为O(n)或O(nlogn)的(数据范围) 思索,如果题目要求1次中位数,好求!排个序,取a[(n+1)/2]就好了 [这道题n的前提是奇数哈] 可是???要求多次中位数,而且是每次加入两个数后,再求一次? 别慌!!!已知中位数的性质是跟数值的顺序有关的. 顺序?大家想一想有哪个数据结构能够动态维护数列顺序,并1次操作复杂度在O(logn)之内 那当然是堆[肯定用优先队列啦]^_^ 方式:[对顶堆] 不…
2015-07-16 问题简述: 动态求取中位数的问题,输入一串数字,每输入第奇数个数时求取这些数的中位数. 原题链接:http://poj.org/problem?id=3784 解题思路: 求取中位数的方法常常想到使用堆来实现:取一个大顶堆,一个小顶堆,使大顶堆的堆顶记录中位数,因此,要时刻保持大顶堆堆顶元素小于小顶堆堆顶元素,且大顶堆元素个数等于小顶堆元素个数或等于小顶堆元素个数加一. 以下有两种堆得实现方法: 一:直接使用STL中的函数(make_heap,push_heap,pop_h…
题目连接 http://acm.hdu.edu.cn/showproblem.php?pid=3282 Running Median 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 the median (middle value) of th…
维护序列的动态中位数 第一次用链表做题..感觉指针指来指去也挺麻烦的.. 本题链表解法就是用数组模拟出一个链表,然后离线输入所有数,排序,按照输入顺序在链表里删除元素,一次性删掉两个,然后中位数指针对应移动即可 #include<iostream> #include<cstring> #include<cstdio> #include<algorithm> using namespace std; #define maxn 10004 struct smc{…
题目描述 给出 $n$ 个数 $a_1,a_2,...,a_n$ ,将其排为序列 $\{p_i\}$ ,满足 $\{前\ i\ 个数的中位数\}$ 单调不降.求字典序最大的 $\{p_i\}$ . 其中,对于一个长度为 $m$ 的数列,若 $m$ 为奇数,则中位数为从小到大第 $\lceil\frac m2\rceil$ 大的数:若 $m$ 为偶数,则中位数为从小到大第 $\frac m2$ 大和第 $\frac m2+1$ 大的数的平均值. 题解 对顶堆+STL-set 显然如果已经知道了这个…
Running Median Time Limit: 1 Sec  Memory Limit: 256 MB 题目连接 http://acm.hdu.edu.cn/showproblem.php?pid=3282 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…
https://vjudge.net/problem/HDU-4261 对于一个长2000的数列划分最多25个块,每块代价为块内每个数与块内中位数差的绝对值之和,求最小总代价. 套路化地,设$f[i][j]$表示第$i$位,划了$j$块最小代价.然后dp.$O(n^3k)$不必说.($logn$和$k$看成同数量级,其实是$O(n^3(k+logn))$) 然后重点在于找中位数.上述暴力浪费在于每段区间中位数都要寻找一遍.可以用对顶堆(其实是不想写平衡树,或者不会更优秀,码量更小的玩意儿了),动…
题意:维护一个序列,两种操作 1.插入一个数 2.输出中位数(若长度为偶数,输出中间两个较小的那个) 对顶堆 维护一个小根堆,一个大根堆,大根堆存1--mid,小根堆存mid+1---n 这样堆顶必有中位数. 每次操作后维护两个堆元素数量,保证一个比另一个多1或相等 #include<cstdio> #include<iostream> #include<algorithm> #include<queue> using namespace std; #def…
这道题是提高+省选-的难度,做出来的话对数据结构题目的理解会增加很多. 可以使用一种叫做对顶堆的东西,对顶堆是在线维护第n小的logn的算法.大概的思路是,假如我们要找的是第n小,我们就维护一个大小为n的(位于下方的)大顶堆,(位于上方的)小顶堆中每个元素都比大顶堆的大.在这道题中,n不变时每次有新的比他小的就把堆顶弹出到对顶(也就是小顶堆)的堆顶,每次n扩大的时候就从(上面的)小顶堆里取出堆顶放进大顶堆的堆顶…… 但是看样子应该其他平衡树也是可以解决这个问题的.比如支持快速名次的splay?还…
priority_queue实现的对顶堆,细节超级多WA了十几次--但是理论上是最简便的orz其实是我已经不会写平衡树了 枚举左端点,显然要把这一段的高度搞成(l,l+k-1)的高度中位数,所以需要一个支持插入删除查询中位数的东西,我们使用对顶堆 然后关于删除,我们手动维护size和sum,删的时候直接减掉就行,然后堆里面放二元组高度和i,需要使用堆顶的时候,把i<l的pop掉就是可用堆顶了 注意q1最大值<=q2最小值,虽然判了但是还是会WA,在调整size的时候顺便判一下即可 #inclu…
[题目链接] http://poj.org/problem?id=3784 [算法] 对顶堆算法 要求动态维护中位数,我们可以将1-M/2(向下取整)小的数放在大根堆中,M/2+1-M小的数放在小根堆中 每次插入元素时,先将插入元素与小根堆堆顶比较,如果比堆顶小,则插入小根堆,否则,插入大根堆,然后,判断两个堆 的元素个数是否平衡,若不平衡,则交换两个堆的堆顶 [代码] #include <algorithm> #include <bitset> #include <ccty…
Luogu P1168 Luogu P1801 UVA 501(洛谷Remote Judge) 前置知识:堆.优先队列STL的使用 对顶堆 是一种在线维护第\(k\)小的算法. 其实就是开两个堆,一个是大根堆,一个是小根堆.两个堆的根相对. 下面借助题目P1168进行详细分析. P1168 题意很好理解,不多作分析. 显然当\(i=1\)时,中位数就是\(a[1]\),记为\(mid\). 我们可以使用对顶堆,把比\(mid\)小的存入大根堆,比mid大的存入小根堆. 当我们已经加入奇数个元素时…
显然答案是将一段区间全部转化成了其中位数这样的话,需要维护一个数据结构支持查询当前所有数中位数对顶堆 用两个堆将 < 中位数的数放入大根堆将 > 中位数的数放入小根堆这样就会存在删除操作 删除的时候由于无法快速删除只需做个标记,标记该数被删除了一次并且堆的实际大小也应该另外记录维护 在标记时需要更改相应的堆的大小与权值答案就非常显然了 #include <bits/stdc++.h> using namespace std; #define gc getchar() inline…
没错我就是专门找对顶堆练习题的.现在感觉对顶堆使用面有点狭窄.这道题由于我询问是随时间单调增的,而且数据比较友好,应该是插入几次就询问一下的.而中位数那题也是经常询问的.如果查询的东西不单调,或者查询过少,对顶堆都会退化,可能一次维护就要$nlogn$,所以他只适用于经常询问单调增排名的问题.(←个人理解,不服可以来怼我) 所以还是主席树或者平衡树更稳一些啊,但码量问题..不写了 #include<iostream> #include<cstdio> #include<cst…
依次读入一个整数序列,每当已经读入的整数个数为奇数时,输出已读入的整数构成的序列的中位数. 输入格式 第一行输入一个整数PP,代表后面数据集的个数,接下来若干行输入各个数据集. 每个数据集的第一行首先输入一个代表数据集的编号的整数. 然后输入一个整数MM,代表数据集中包含数据的个数,MM一定为奇数,数据之间用空格隔开. 数据集的剩余行由数据集的数据构成,每行包含10个数据,最后一行数据量可能少于10个,数据之间用空格隔开. 输出格式 对于每个数据集,第一行输出两个整数,分别代表数据集的编号以及输…
本题使用对顶堆做法. 为了动态维护中位数,我们可以建立两个堆 :一个大根对,一个小根堆. 用法:在动态维护的过程中,设当前的长度为length,大根堆存从小到大排名 $1 \thicksim \dfrac{m}{2} $ 的整数,小根堆存小到大排名 $ \dfrac{m}{2} + 1 \thicksim m $ 的整数 如何动态维护?顾名思义,动态,即边输入边处理.显然,为了维护中位数,我们还要不断地维护两个堆的\(size\) 每次新读入一个值,就 \(\begin{cases}插入大根堆&…
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…
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 the median (middle value) of the elements received so far. Input The first line of input contains…
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 the median (middle value) of the elements received so far. Input The first line of input contains…
题目描述 Black Box是一种原始的数据库.它可以储存一个整数数组,还有一个特别的变量i.最开始的时候Black Box是空的.而i等于0.这个Black Box要处理一串命令. 命令只有两种: ADD(x):把x元素放进BlackBox; GET:i加1,然后输出Blackhox中第i小的数. 记住:第i小的数,就是Black Box里的数的按从小到大的顺序排序后的第i个元素.例如: 我们来演示一下一个有11个命令的命令串.(如下图所示) 现在要求找出对于给定的命令串的最好的处理方法.AD…
Description Moscow is hosting a major international conference, which is attended by n scientists from different countries. Each of the scientists knows exactly one language. For convenience, we enumerate all languages of the world with integers from…
题目链接:http://poj.org/problem?id=3784 题目大意:依次输入n个数,每当输入奇数个数的时候,求出当前序列的中位数(排好序的中位数). 此题可用各种方法求解. 排序二叉树方法,每个结点保存以其为根的左右子树中数的个数.如果数据出的够严格,这种方法会被卡的,除非是通过动态调整维持树的高度较小. 排序二叉树的代码如下: #include <cstdio> using namespace std; #define N 20000 struct Node { int v;…
题面传送门 题意: 一条河将大地分为 \(A,B\) 两个部分.两部分均可视为一根数轴. 有 \(n\) 名工人,第 \(i\) 名的家在 \(x_i\) 区域的 \(a_i\) 位置,公司在 \(y_i\) 区域的 \(b_i\) 位置. 现在你可以建立 \(k\) 座桥,在 \(x\) 位置建立一座桥可以连接 \(A\) 区域的 \(x\) 位置和 \(B\) 区域的 \(x\) 位置,桥长为 \(1\) 个单位长度. 设 \(d_i\) 为第 \(i\) 名工人从家到公司走过的最短距离,求…
T1:Median   线性筛+桶+随机化(??什么鬼?).   首先,题解一句话秀到了我: 考虑输入如此诡异,其实可以看作随机数据   随机数据??   这就意味着分布均匀..   又考虑到w<=k<=n   可以用桶了.   中位数暴力算的话是排序后取中间.   但是时间明显不允许.只能\(O(n)\)过掉.所以要维护两个中位数指针(k%2==1当然就是一个了).   由于数据随机,分布均匀,所以可以直接跳桶.   笑死,我当时不信还把数据输了出去,发现有的相邻数据差了几百,就这还能直接跳…
LintCode 81. Data Stream Median (Hard) 思路: 用一个大根堆保存较小的一半数, 一个小根堆保存较大的一半数. 每次根据num和两个堆顶的数据决定往哪个堆里面放. 放完后进行平衡确保两个堆的size差不超过1. 利用两个堆的size和堆顶值计算median. 大根堆可以表示为priority_queue<int, vector<int>, less<int>>, 其实priority_queue<int>默认就是大根堆.…