对顶堆求中位数
可以用 $2$ 个堆维护滑动区间的中位数,分别是小根堆和大根堆.(一般使用multiset或优先队列作为数据结构)
做法:使用2个堆,大根堆维护较小的值,小根堆维护较大的值,并使2个堆中的元素数目差不大于 $1$
期间可以不断地添加或删除元素
代码用multiset举例
int x = a[i];
//添加元素
if (i == 1){
q1.insert(x);
}else if (x > *q1.begin()){
q2.insert(x);
}else{
q1.insert(x);
}
//元素调整
while (abs(int(q1.size() - q2.size())) > 1){
if (q1.size() > q2.size()){
int y = *q1.begin();
q2.insert(y);
q1.erase(q1.begin());
}else{
int y = *q2.begin();
q1.insert(y);
q2.erase(q2.begin());
}
}
下标相减(形如a[j] - a[i] = j - i)
CF经典套路,先把 $a_i 的数值变成 a_i - i$,这样题目就会清晰很多
(abc和23济南K均出过)