#include<bits/stdc++.h>
using namespace std;
int n,a[100010],x;
priority_queue<int> pmx; // 符号+ 比中位数小或等于的数
priority_queue<int> pmi; // 符号- 比中位数大于的数
int main(){
cin >> n;
for(int i=1;i<=n;i++)cin >>a[i];
cout << a[1] << endl;pmx.push(a[1]); // 先处理第一个数
for(int i=3;i<=n;i+=2){
for(int j=1;j>=0;j--){ // 每次处理两个
if(pmi.size()==0) x = pmx.top();
else x = -pmi.top(); // 防止堆中无元素导致错误
if(x<a[i-j])pmi.push(-a[i-j]); // 添加元素
else pmx.push(a[i-j]);
}
// 将两个堆的长度差减小
while(pmx.size()>pmi.size()+1){
pmi.push(-pmx.top());
pmx.pop();
}
while(pmx.size()<=pmi.size()){
pmx.push(-pmi.top());
pmi.pop();
}
cout << pmx.top() << endl; // 输出
}
return 0;
}
P1168 中位数
题解
只需要维护一个中间大小的数,我们可以试着使用两个优先队列(一个大根堆,用于记录比中位数小的数,堆顶为最小数中的最大值;一个小根堆,同前,用于记录比中位数大的数,堆顶为最大数中的最小值),使两个队列的长度差小于1,每次只需要获取中间的值即可。
我的代码中设置大根堆默认多一个,每次查询只需要输出大根堆的堆顶即可。(小根堆使用负数代替)