对顶堆求中位数

可以用 $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均出过)