首页 > 其他分享 >对顶堆例题

对顶堆例题

时间:2023-06-29 20:46:56浏览次数:44  
标签:q1 大根堆 q2 元素 个数 小根堆 例题

例题:洛谷中位数

以下题解来自于 https://www.luogu.com.cn/blog/SeanMoe/solution-p1168

使用两个堆,大根堆维护较小的值,小根堆维护较大的值

即小根堆的堆顶是较大的数中最小的,大根堆的堆顶是较小的数中最大的

将大于大根堆堆顶的数(比所有大根堆中的元素都大)的数放入小根堆,小于等于大根堆堆顶的数(比所有小根堆中的元素都小)的数放入大根堆

那么就保证了所有大根堆中的元素都小于小根堆中的元素

于是我们发现对于大根堆的堆顶元素,有【小根堆的元素个数】个元素比该元素大,【大根堆的元素个数-1】个元素比该元素小;

同理,对于小跟堆的堆顶元素,有【大根堆的元素个数】个元素比该元素小,【小根堆的元素个数-1】个元素比该元素大;

那么维护【大根堆的元素个数】和【小根堆的元素个数】差值不大于1之后,元素个数较多的堆的堆顶元素即为当前中位数;(如果元素个数相同,那么就是两个堆堆顶元素的平均数,本题不会出现这种情况)

根据这两个堆的定义,维护方式也很简单,把元素个数多的堆的堆顶元素取出,放入元素个数少的堆即可

对于部分不会堆的同学,请参照下面各位神犇的算法,或者自行学习堆

下面是代码实现,使用了STL的优先队列作为堆,经过压行仅有24行代码,可读性可能比较低,如果觉得阅读困难可以参照下面各位神犇的代码

#include<bits/stdc++.h>
using namespace std;
int read(){//读入优化
    int x=0;bool f=0;char c=getchar();
    while (c<'0'||c>'9'){if (c=='-')f=1;c=getchar();}
    while (c>='0'&&c<='9'){x=(x<<1)+(x<<3)+(c^48);c=getchar();}
    return f?-x:x;
}
priority_queue<int,vector<int> > q1;//大根堆
priority_queue<int,vector<int>,greater<int> > q2;//小根堆
int main(){
    int n=read();q1.push(read());
    cout<<q1.top()<<endl; 
    for (int i=2;i<=n;i++){
        int input=read();//等同于cin>>input
        if (input>q1.top()) q2.push(input);
            else q1.push(input);
        while (abs(q1.size()-q2.size())>1)
            if (q1.size()>q2.size()){q2.push(q1.top());q1.pop();}
                else{q1.push(q2.top());q2.pop();}
        if (i%2) cout<<(q1.size()>q2.size()?q1.top():q2.top())<<endl;
    }
    return 0;
}

标签:q1,大根堆,q2,元素,个数,小根堆,例题
From: https://www.cnblogs.com/alloverzyt/p/17515150.html

相关文章

  • [数论]GCD&LCM&欧拉函——推柿子+例题
    GCD&LCM&欧拉函——推柿子一、\(\sum_{i=1}^{n}[\gcd(i,n)=d]\)\(\sum_{i=1}^{n}[\gcd(i,n)=d]\)\(=\sum_{i=1}^{\frac{n}{d}}[\gcd(i,\frac{n}{d})=1]\)\(=\phi(\frac{n}{d})\)二、\(\sum_{i=1}^{n}\gcd(i,n)\)\(\sum_{i=1}^{n}\gcd(i,......
  • 计算机组成原理:指令系统、CPU数据通路信号(例题
    分析:由题目可知操作码占4位,所以支持的操作指令为\(2^4\)种指令操作数占6位,其中寻址3位,寄存器编号3位,所以最多有\(2^3\)个通用寄存器主存大小为128KB,机器字长为16位,且按字编址,所以有\(\frac{128KB}{2B}\quad=2^{16}\)个存储单元,即MAR至少16位机器字长为16为,那么MDR至少也......
  • 树状数组讲解与例题 杭电HDU1166,HDU1556,HDU2689
    树状数组的总结树状数组很巧妙地解决了数列的求和与查找,速度很快。树状数组,它改变数列中某一位,或者求某个区间的和,时间复杂度是O(logN);效率大为改善。下面的图片很好的演示了树状数组的存储原理。(图片来自网络)观察图片,会发现:数组c的每一个元素都管辖着一定范围内的数组a元素的和,比如C......
  • 统计学习方法:感知机模型例题
    统计学习方法:感知机模型例题1.感知机学习算法的原始形式2.例题例2.1如图2.2所示的训练数据集,其正实例点是x1=(3,3)T,x2=(4,3)T,负实例点是x3=(1,1)T,试用感知机学习算法的原始形式求感知机模型f(x)=sign(w·x+b)。这里,w=(w(1),w(2))T,x=(x(1),x(2))T。3.线性可分数据集感知机学习......
  • 肖sir__实践题___测试用例题
    实践面试题1、手淘浏览店铺页15s,可以完成任务,放发奖励。请设计测试用 2、用户在pc中选择时间范围后,需要将相应的表格数据下载,请根据这个功能设计功能用例 3、用例设计:某程序实现如下功能:输入3个数据A,B,C,输出以A.B.C为边长组成的三角形的面积。(1<AB,C<100)等价类和边......
  • 搜索例题
    //SatellitePhotographs//农民约翰购买了卫星照片$W\timesH$他的农场像素$(1\leW\le80,1\leH\le1000)$并希望确定最大的“连续”(连接)牧场。//当牧场中的任何一对像素可以通过遍历作为牧场一部分的相邻垂直或水平像素来连接时,牧场是连续的。//每张照片都经过数字增......
  • c++模板例题
    一、问题描述。1 编写一个程序,使用类模板对数组元素进行排序,倒置、查找和求和2 具有对数组元素进行排序,倒置、查找和求和功能,3 然后产生类型实参分别为int型和double型的两个模板类,4 分别对整型数组与双精度数组完成所要求的操作 实现代码: #include<iostream> using name......
  • [每天例题]蓝桥杯 C语言 次数差
    次数差题目  思路分析1.通过字符型数组接收字符串,通过整形数组确定字母出现的次数2.通过for—if寻找出现次数最多与最少的字母,注意,这里有个坑,出现次数最少的字母至少出现一次代码#include<stdio.h>intmain(){ chars[1000]; intnum[26]={0}; intmax=-1,min=10......
  • 动态规划算法基础及leetcode例题
    01基础理论题型:动规基础(斐波那契数列or爬楼梯);背包问题;打家劫舍;股票问题;子序列问题动规误区:只要看懂递推就ok(递推公式只是一部分)解决动态规划应该要思考的几步:状态转移的DP数组以及下标的含义递推公式DP数组为何初始化遍历顺序打印DP数组02例题基础题目509.斐波那......
  • [每天例题]蓝桥杯 C语言 回文日期
    回文日期题目    思路分析1.由于题目要求是找到一定范围日期内的回文日期,所以我们可以采用for遍历日期2.再调用函数先判断闰年,再进行日期合法判断,最后再进行回文数判断3.注意,该日期范围包含起始和结束这两个日期,这里会有一个案例挖坑代码#include<stdio.h>int......