对顶堆学习笔记
文章目录
- **对顶堆学习笔记**
- 介绍
- 例题
- 洛谷 P1168 中位数
- code
介绍
对顶堆是由一个大顶堆和一个小顶堆组合而成的数据结构,与传统堆维护最大数不同,对顶堆用于动态维护第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;
}