对顶堆学习笔记

对顶堆学习笔记

介绍

对顶堆是由一个大顶堆和一个小顶堆组合而成的数据结构,与传统堆维护最大数不同,对顶堆用于动态维护第k大的数。

对于对顶堆,我们可以用两个优先队列来表示两个堆。而他所维护的,我们可以看成一个单调的序列

如图:

注意一下每次加入后,处理一下两个堆的长度必须小于等于1。

例题

洛谷 P1168 中位数

题目传送门

版题

code

#include <bits/stdc++.h>
#define fu(x , y , z) for(int x = y ; x <= z ; x ++)
using namespace std;
const int N = 100005;
int n , a[N] , l1 , l2;
priority_queue<int> s1;
priority_queue<int , vector<int> , greater<int>> s2;
void add (int x) {
    if (s1.empty() && s2.empty()) {
        s1.push (x) , l1 ++;
        return;
    }
    int k = s1.top ();
    if (x >= k) s2.push (x) , l2 ++;
    else s1.push (x) , l1 ++;
    if (l1 - l2 > 1) {
        k = s1.top ();
        s1.pop();
        s2.push(k);
        l1 -- , l2 ++;
    }
    if (l2 - l1 > 1) {
        k = s2.top ();
        s2.pop();
        s1.push(k);
        l2 -- , l1 ++;
    }
}
int query () { return l1 > l2 ? s1.top() : s2.top(); }
int main () {
    scanf ("%d" , &n);
    fu (i , 1 , n)
        scanf ("%d" , &a[i]);
    for (int i = 1 ; i <= n ; i += 2) {
        if (i == 1)
            add (a[1]);
        else {
            add (a[i - 1]);
            add (a[i]);
        }
        // cout << s1.top () << " " << s2.top() << "\n";
        printf ("%d\n" , query());
    }
    return 0;
}
posted @   2020fengziyang  阅读(29)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 周边上新:园子的第一款马克杯温暖上架
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· Ollama——大语言模型本地部署的极速利器
· DeepSeek如何颠覆传统软件测试?测试工程师会被淘汰吗?
· 使用C#创建一个MCP客户端
点击右上角即可分享
微信分享提示