数据结构——对顶堆

news2024/12/12 15:11:31

对顶堆

由一个大根堆和一个小根堆组成,小根堆里面的数永远比大根堆里面的数要大

用途:用于动态维护区间内第k大的数,要比线段树和动态平衡树写起来更简单

 比如说我们要维护第k大的数,那么我们肯定是将前k大的数放进小根堆,小根堆的堆顶就是第k大的数

我们来看一下维护第k大的数的代码

1.建立大根堆和小根堆

priority_queue<int> qmax;  //相当于大顶堆
priority_queue<int,vector<int>,greater<int>> qmin;  //相当于小顶堆

2.如果小根堆是空的,或者说当前元素大于小根堆的堆顶元素,那么就将当前元素存入小根堆,否则就存入大根堆 

		if(qmin.empty()||a>=qmin.top())
		{
			qmin.push(a);
		}
		else
		{
			qmax.push(a);
		}

3.大、小根堆的维护,当我们小根堆的元素,不满k个,就将大根堆的堆顶元素弹入小根堆,如果我们当前小根堆的元素超过了k个,就将小根堆的堆顶元素摊入大根堆 

		while(qmin.size()>k)
		{
			qmax.push(qmin.top());
			qmin.pop();
		}
		while(qmin.size()<k&&!qmax.empty())
		{
			qmin.push(qmax.top());
			qmax.pop();
		}

4.查询第k大的元素,访问小根堆的堆顶元素

cout<<qmin.top()<<"\n";

 例题

P1168 中位数

思路:去求奇数项的中位数,这个中位数的下标是在不断变化的,很板的一种动态维护第k大的元素的板题,直接套用对顶堆代码即可

#include<bits/stdc++.h>
using namespace std;
#define int long long
int n,k;
int a;
priority_queue<int> qmax;
priority_queue<int,vector<int>,greater<int> > qmin;
signed main()
{
	cin>>n;
	for(int i=1;i<=n;i++)
	{
		cin>>a;
		if(i%2==1)
		{
			k=(i+1)/2;
		}
		if(qmin.empty()||a>=qmin.top())
		{
			qmin.push(a);
		}
		else
		{
			qmax.push(a);
		}
		while(qmin.size()>k)
		{
			qmax.push(qmin.top());
			qmin.pop();
		}
		while(qmin.size()<k&&!qmax.empty())
		{
			qmin.push(qmax.top());
			qmax.pop();
		}
		if(i%2==1)
		{
			cout<<qmin.top()<<"\n";
		}
	}
	return 0;
}

 P7072 [CSP-J2020] 直播获奖

 思路:第一眼看上去,获奖分数线为多少?即i*w/100位置上的人的分数是多少,翻译过来还是第k大的元素是多少,动态维护第k大的对顶堆板题

直接写就行

#include<bits/stdc++.h>
using namespace std;
#define int long long
int n,k;
double w;
int a;
priority_queue<int>qmax;
priority_queue<int,vector<int>,greater<int> >qmin;
signed main()
{
	cin>>n>>w;
	for(int i=1;i<=n;i++)
	{
		cin>>a; 
		int z=floor(i*w/100);
		k=max(1LL,z);
		if(qmin.empty()||a>=qmin.top())
		{
			qmin.push(a);
		}
		else
		{
			qmax.push(a);
		}
		while(qmin.size()<k&&!qmax.empty())
		{
			qmin.push(qmax.top());
			qmax.pop();
		}
		while(qmin.size()>k)
		{
			qmax.push(qmin.top());
			qmin.pop();
		}
		cout<<qmin.top()<<" ";
	}
	return 0;
} 

P2085 最小函数值

 思路:我们发现a,b,c都是正数,那么其堆成周-b/2*a,永远都在负数的位置,也就是说,这n个函数,在0~正无穷内都是单调递增的,那么我们可以考虑一种剪枝的O(n*m)的写法,我们首先创建一个大顶堆,存储前k小的元素,我们在最外层遍历n个函数,内层遍历m个数,当n为1的时候,先将m个函数值存进去,然后当后续的函数,如果存在比堆顶元素小的,就存进大顶堆,弹出堆顶

,如果比堆顶元素大,那就立刻结束当前内层循环,因为后面也会比堆顶元素大,。

直到双重循环遍历完,然后输出倒序前m个即可

//P2085 最小函数值
#include<bits/stdc++.h>
using namespace std;
#define int long long

int n,m;
priority_queue<int>qmax;
int a,b,c;
int f;
int ans[200005];
signed main()
{
	cin>>n>>m;
	for(int i=1;i<=n;i++)
	{
		cin>>a>>b>>c;
		for(int j=1;j<=m;j++)
		{
			f=a*j*j+b*j+c;
			if(i==1)
			{
				qmax.push(f);
			}
			else
			{
				if(f<qmax.top())
				{
					qmax.pop();
					qmax.push(f);
				}
				else
				{
					break;
				}
			}
		}
	}
	for(int i=1;i<=m;i++)
	{
		ans[i]=qmax.top();
		qmax.pop();
	}
	for(int i=m;i>=1;i--)
	{
		cout<<ans[i]<<" ";
	}
	return 0;
}

P1631 序列合并

思路:和上面那个一个思路,我们写一个有剪枝的O(n^2)的写法 ,和上面那个思路差不多

#include<bits/stdc++.h>
using namespace std;
#define int long long
int n;
int a[100005];
int b[100005];
int ans[100005];
priority_queue<int> q;
signed main()
{
	cin>>n;
	for(int i=1;i<=n;i++)
	cin>>a[i];
	for(int i=1;i<=n;i++)
	cin>>b[i];
	sort(a+1,a+1+n);
	sort(b+1,b+1+n);
	int k;
	for(int i=1;i<=n;i++)
	{
		for(int j=1;j<=n;j++)
		{
			k=a[i]+b[j];
			if(i==1)
			{
				q.push(k);
			}
			else
			{
				if(k<q.top())
				{
					q.pop();
					q.push(k);
				}
				else
				{
					break;
				}
			}
		}
	}
	for(int i=1;i<=n;i++)
	{
		ans[i]+=q.top();
		q.pop();
	}
	for(int i=n;i>=1;i--)
	cout<<ans[i]<<" ";
	return 0;
}

P1801 黑匣子

思路:我们很容易发现,题目还是动态求第k小的,因此我们要将前k小的,放入大根堆中,当我们大根堆位空,或者说当前元素小于大根堆的堆顶,就存进来,我们用vis[i]去统计要进行输出的位置即可

#include<bits/stdc++.h>
using namespace std;
#define int long long
int n,m;
int a[200005];
int b[200005];
int vis[200005];
priority_queue<int> qmax;
priority_queue<int,vector<int>,greater<int> > qmin;

signed main()
{
	cin>>n>>m;
	for(int i=1;i<=n;i++)
	{
		cin>>a[i];
	}
	for(int i=1;i<=m;i++)
	{
		cin>>b[i];
		vis[b[i]]++;
	}
	int k=0;
	for(int i=1;i<=n;i++)
	{
		if(qmax.empty()||a[i]<qmax.top())
        {
        	qmax.push(a[i]);
		}
        else
        {
        	qmin.push(a[i]);
		}
		while(vis[i])
		{
			k++;
			while(qmax.size()<k)
			{
				qmax.push(qmin.top());
				qmin.pop();
			}
			while(qmax.size()>k)
			{
				qmin.push(qmax.top());
				qmax.pop();
			}
			cout<<qmax.top()<<"\n";
			vis[i]--;
		}
	}
	return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2258296.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

设计模式之原型模式:深入浅出讲解对象克隆

~犬&#x1f4f0;余~ “我欲贱而贵&#xff0c;愚而智&#xff0c;贫而富&#xff0c;可乎&#xff1f; 曰&#xff1a;其唯学乎” 原型模式概述 在我们的日常生活中&#xff0c;经常会遇到"复制"这样的场景。比如我们在准备文件时&#xff0c;常常会复印一份原件&a…

Elasticsearch Serverless 中的数据流自动分片

作者&#xff1a;来自 Elastic Andrei Dan 在 Elastic Cloud Serverless 中&#xff0c;我们根据索引负载自动为数据流配置最佳分片数量&#xff0c;从而使用户无需摆弄分片。 传统上&#xff0c;用户会更改数据流的分片配置&#xff0c;以处理各种工作负载并充分利用可用资源。…

【Golang】Go语言编程思想(六):Channel,第四节,Select

使用 Select 如果此时我们有多个 channel&#xff0c;我们想从多个 channel 接收数据&#xff0c;谁来的快先输出谁&#xff0c;此时应该怎么做呢&#xff1f;答案是使用 select&#xff1a; package mainimport "fmt"func main() {var c1, c2 chan int // c1 and …

MindSearch深度解析实践

任务要求&#xff1a;在 官方的MindSearch页面 复制Spaces应用到自己的Spaces下&#xff0c;Space 名称中需要包含 MindSearch 关键词&#xff0c;请在必要的步骤以及成功的对话测试结果当中 1.在github codespace中配置环境 conda create -n mindsearch python3.10 -y conda…

【PyQt5教程 二】Qt Designer 信号与槽的使用方法及PyQt5基本小部件说明

目录 一、信号与槽机制&#xff1a; 二、信号与槽使用方法&#xff1a; &#xff08;1&#xff09;使用Qt Designer 的信号与槽编辑器&#xff1a; &#xff08;2&#xff09;使用固定语法直接建立信号槽连接&#xff1a; 三、PyQt小部件及其触发信号&#xff1a; &#x…

基于PHP课堂签到系统的设计与实现

摘 要 随着教育业的迅速发展和学生人数的不断增加&#xff0c;导致在班级登记制度中传统的“点到”方式不能适应学校的实际需要。从而需要设计一个好的课堂签到系统将会对课堂签到管理工作带来事半功倍的效果。文章着重介绍了基于实践应用的班级签到系统的开发流程&#xff0c…

CSS学习记录11

CSS布局 - display属性 display属性是用于控制布局的最终要的CSS属性。display 属性规定是否/如何显示元素。每个HTML元素都有一个默认的display值&#xff0c;具体取决于它的元素类型。大多数元素的默认display值为block 或 inline。 块级元素&#xff08;block element&…

高效利用资源:分布式有状态服务的高可靠性设计

在分布式系统设计中&#xff0c;实现有状态服务的高可靠性通常采用主备切换的方式。当主服务停止工作时&#xff0c;备服务接管任务&#xff0c;例如通过Keepalive实现VIP的切换以保证可用性。然而&#xff0c;这种方式存在资源浪费的问题&#xff0c;因为备服务始终处于空转状…

重生之我在异世界学智力题(2)

大家好&#xff0c;这里是小编的博客频道 小编的博客&#xff1a;就爱学编程 很高兴在CSDN这个大家庭与大家相识&#xff0c;希望能在这里与大家共同进步&#xff0c;共同收获更好的自己&#xff01;&#xff01;&#xff01; 本文目录 引言智力题&#xff1a;逃离孤岛智力题&a…

论文浅尝 | SAC-KG:利用大语言模型作为领域知识图谱熟练的自动化构造器(ACL2024)...

笔记整理&#xff1a;杜超超&#xff0c;天津大学硕士&#xff0c;研究方向为自然语言处理、大语言模型 论文链接&#xff1a;https://aclanthology.org/2024.acl-long.238/ 发表会议&#xff1a;ACL 2024 1. 动机 知识图谱&#xff08;KG&#xff09;在各个专业领域的知识密集…

Python机器视觉的学习

一、二值化 1.1 二值化图 二值化图&#xff1a;就是将图像中的像素改成只有两种值&#xff0c;其操作的图像必须是灰度图。 1.2 阈值法 阈值法&#xff08;Thresholding&#xff09;是一种图像分割技术&#xff0c;旨在根据像素的灰度值或颜色值将图像分成不同的区域。该方法…

Elasticsearch高性能实践

前言 本方案主要从运维层面分析es是实际生产使用过程中的参数优化&#xff0c;深入理解es各个名词及含义&#xff0c;深入分析es的使用过程中应注意的点&#xff0c;详细解释参数设置的原因以及目的&#xff0c;主要包括系统层面&#xff0c;参数层面。除此之外&#xff0c;优…

笔记本外接显示屏没声音

1、笔记本正常有声音&#xff0c;但是外接显示屏后没有声音了怎么回事呢&#xff1f;原来外接显示屏后笔记本的声音输出会自动选择显示屏的音频输出&#xff0c;但是显示屏可能没有声音输出所以导致笔记本没有声音。 2、解决办法&#xff1a;打开笔记本设置&#xff0c;选择声…

JavaWeb学习(4)(四大域、HttpSession原理(面试)、SessionAPI、Session实现验证码功能)

目录 一、web四大域。 &#xff08;1&#xff09;基本介绍。 &#xff08;2&#xff09;RequestScope。(请求域) &#xff08;3&#xff09;SessionScope。(会话域) &#xff08;4&#xff09;ApplicationScope。(应用域) &#xff08;5&#xff09;PageScope。(页面域) 二、Ht…

用人话讲计算机:Python篇!(十二)正则运算+re模块

目录 一、正则表达式 &#xff08;1&#xff09;什么是正则表达式 &#xff08;2&#xff09;它的结构及使用 示例&#xff1a; 1.字符 . &#xff08;←这里有个小点哦&#xff09; 2.字符 | 3.字符 [ ] 4.字符^ 5.字符\d &#xff08;3&#xff09;补充&#xff…

力扣打卡12:复原IP地址

链接&#xff1a;93. 复原 IP 地址 - 力扣&#xff08;LeetCode&#xff09; 这道题需要对字符串进行操作&#xff0c;我选择了三层循环&#xff0c;其实还可以递归。 我在循环时进行了剪枝&#xff0c;比如一些情况直接跳出循环。 我的代码&#xff1a; class Solution { p…

说下JVM中一次完整的GC流程?

大家好&#xff0c;我是锋哥。今天分享关于【说下JVM中一次完整的GC流程&#xff1f;】面试题。希望对大家有帮助&#xff1b; 说下JVM中一次完整的GC流程&#xff1f; 1000道 互联网大厂Java工程师 精选面试题-Java资源分享网 在JVM中&#xff0c;垃圾回收&#xff08;GC&am…

vs配置c++标准

在 vcxproj 文件中添加 <LanguageStandard>stdcpp17</LanguageStandard> 和在 Visual Studio 属性页面中设置 “C语言标准” 为 “ISO C17 标准 (/std:c17)” 是完全等价的。 它们的对应关系是&#xff1a; VS属性页面中的设置&#xff1a; 项目 -> 属性 ->…

TcpServer 服务器优化之后,加了多线程,对心跳包进行优化

TcpServer 服务器优化之后&#xff0c;加了多线程&#xff0c;对心跳包进行优化 TcpServer.h #ifndef TCPSERVER_H #define TCPSERVER_H#include <iostream> #include <winsock2.h> #include <ws2tcpip.h> #include <vector> #include <map> #…

风控大讲堂|游戏黑产情报挖掘与治理

您的产品有没有遇到过被薅羊毛了&#xff1f;网络游戏行业的繁荣&#xff0c;催生了一批围绕游戏而生的职业玩家&#xff0c;他们利用多开、修改器等手段&#xff0c;疯狂薅游戏资源&#xff0c;破坏游戏经济平衡&#xff0c;给游戏公司带来了难以估量的巨大损失。那么针对此类…