当前位置: 首页 > news >正文

对顶堆

对顶堆

所谓对顶堆,有点像双栈对顶那样,一个是小根堆,另一个是大根堆。假设 g g g 是大根堆, l l l 是小根堆,那么观察下图不难发现,两堆中间的元素,左边都是小于它的,且 g . t o p ( ) g.top() g.top() 是小于它的最大值,右边都是大于它的,且 l . t o p ( ) l.top() l.top() 是大于它的最小值
在这里插入图片描述

中位数问题

现在有一个序列动态输入,求每次输入后的中位数

利用上述对顶堆的思想,中位数肯定是中间的数,那么 g g g l l l 维护的两个数就是动态输入时最中间的两个数,因此当两堆大小相等时,即输入序号为偶数时,中位数为二者的 t o p ( ) top() top() 求和除以二;当两堆大小不相等时,即输入序号为奇数时,肯定有一个堆的的大小比另外一个堆大一,那么输出堆顶即可

注意

1.初始时两堆都为空,那么就随便选择一个堆进入

2.如果当前插入元素比大根堆的 t o p ( ) top() top() ——即当前中位数左边的值小时,就插入到大根堆,同理在比小根堆 t o p ( ) top() top() 大时插入到小根堆

3.如果输入序列为升序或者降序,不可能都插入到一个堆中,根据上述奇偶性,两堆大小要么差一要么相等,因此当一个堆大小比另外一个堆大 2 2 2及以上时,就对弹一下

因此我们得到如下函数:

priority_queue<double> g;
priority_queue<double, vector<double>, greater<double> > l;
int n;
double now;

void insert(int x) {   //必要时为double
    if(!g.size() || x < g.top()) g.push(x);  //条件放在一起判断并注意先后
    else l.push(x);
    //对弹
    if(g.size() > l.size() + 1) l.push(g.top()), g.pop();  //g.size() - l.size() > 1会运行错误
    if(l.size() > g.size() + 1) g.push(l.top()), l.pop();
}

POJ3784

对顶堆求中位数的裸题

#include <iostream>
#include <queue>
#include <algorithm>
using namespace std;
const int maxn = 1e4 + 10;
priority_queue<int> g;
priority_queue<int, vector<int>, greater<int> > l;

void insert(int x) {
    if(!g.size() || x < g.top()) g.push(x);
    else l.push(x);
    if(g.size() > l.size() + 1) l.push(g.top()), g.pop();
    if(l.size() > g.size() + 1) g.push(l.top()), l.pop();
}

int main() {
    int t, n, x, kase, mid;
	scanf("%d", &t);
	while(t--) {
		while (g.size()) g.pop();
		while (l.size()) l.pop();
		scanf("%d%d", &kase, &n);
		printf("%d %d\n",kase, (n + 1) / 2);
		int cnt = 0;
		for (int i = 1; i <= n; i++) {
			scanf("%d", &x);
			insert(x);
			if (i & 1) {
				printf("%d ", g.size() > l.size() ? g.top() : l.top());
				if (++cnt == 10 && i != n) {
                    printf("\n");
                    cnt = 0;
                }
			}
		}
		printf("\n");
	}
	return 0;
}

相关文章:

  • Android开发指南-用户界面-绑定数据
  • UVa 1152 - 4 Values whose Sum is 0(hash_map/hash/二分查找)
  • Android开发指南-用户界面-绘制视图
  • 摆脱枯燥的文字描述——markdown表情包黑科技
  • 真正要寻找的是那些充满了热情,希望做出点成绩来的人
  • UVa11134 Fabled Rooks(贪心)
  • 给各位支持我的朋友的致歉信
  • 计算几何——极角排序
  • 不同差异程度商品的电子商务策略
  • UVa1606 Amphiphilic Carbon Molecules(极角排序+扫描线)
  • 滴水之光 折射太阳
  • POJ3061 Subsequence(尺取法)
  • UVa11572 Unique Snowflakes(尺取法)
  • 对MM平台的一些思考
  • 2019 ICPC Asia Taipei - Hsinchu Regional
  • 【Linux系统编程】快速查找errno错误码信息
  • 【个人向】《HTTP图解》阅后小结
  • Docker 笔记(1):介绍、镜像、容器及其基本操作
  • FineReport中如何实现自动滚屏效果
  • JavaScript 事件——“事件类型”中“HTML5事件”的注意要点
  • JS变量作用域
  • k8s如何管理Pod
  • Mysql优化
  • Object.assign方法不能实现深复制
  • PHP的类修饰符与访问修饰符
  • 一些css基础学习笔记
  • 自动记录MySQL慢查询快照脚本
  • ​ArcGIS Pro 如何批量删除字段
  • ​VRRP 虚拟路由冗余协议(华为)
  • #1014 : Trie树
  • #include
  • #stm32驱动外设模块总结w5500模块
  • #每日一题合集#牛客JZ23-JZ33
  • (51单片机)第五章-A/D和D/A工作原理-A/D
  • (pytorch进阶之路)扩散概率模型
  • (Spark3.2.0)Spark SQL 初探: 使用大数据分析2000万KF数据
  • (超简单)构建高可用网络应用:使用Nginx进行负载均衡与健康检查
  • (二)七种元启发算法(DBO、LO、SWO、COA、LSO、KOA、GRO)求解无人机路径规划MATLAB
  • **Java有哪些悲观锁的实现_乐观锁、悲观锁、Redis分布式锁和Zookeeper分布式锁的实现以及流程原理...
  • **PHP二维数组遍历时同时赋值
  • *Algs4-1.5.25随机网格的倍率测试-(未读懂题)
  • .htaccess配置常用技巧
  • .Net CF下精确的计时器
  • .NET Core 通过 Ef Core 操作 Mysql
  • .Net Web窗口页属性
  • .NET的微型Web框架 Nancy
  • .NET开发不可不知、不可不用的辅助类(三)(报表导出---终结版)
  • .NET下的多线程编程—1-线程机制概述
  • .NET性能优化(文摘)
  • .NET中的十进制浮点类型,徐汇区网站设计
  • .sh文件怎么运行_创建优化的Go镜像文件以及踩过的坑
  • .w文件怎么转成html文件,使用pandoc进行Word与Markdown文件转化
  • @configuration注解_2w字长文给你讲透了配置类为什么要添加 @Configuration注解
  • @拔赤:Web前端开发十日谈
  • [ Linux 长征路第五篇 ] make/Makefile Linux项目自动化创建工具