先附上对顶堆的格式
https://blog.csdn.net/qq_34416123/article/details/82972445
priority_queue<int> q1; //大根堆
priority_queue<int, vector<int>, greater<int> > q2; //小根堆
void insert(int x)
{
if (!q2.size() || x > q2.top()) q2.push(x);
else q1.push(x);
if (q1.size() > q2.size() + 1)
{
q2.push(q1.top());
q1.pop();
}
if (q2.size() > q1.size() + 1)
{
q1.push(q2.top());
q2.pop();
}
}
Description
Ging打算在一条长街上开一些冷饮店,制作冷饮的材料存放在仓库中,而仓库只能设置在某个冷饮店中。
为了材料运输的方便,Ging希望所有冷饮店到仓库的距离之和尽可能小。
出于资金的限制,Ging将陆续在这条长街上的建设冷饮店(开始前没有冷饮店),每次增设冷饮店后,出于材料运输要求的考虑,可能要改动仓库的位置。
他希望你计算每次增设店铺后的仓库位置,并输出此时所有冷饮店到仓库的距离之和。
Input
第一行包含一个整数n(1<=n<=2*10^5),表示 Ging 计划一共要建设n个冷饮店
接下来n行,每行一个整数pi(1<=pi<=1e9),表示在pi处建设一个新的冷饮店
数据保证不存在两家店开在同一处
Output
输出 nn 行,每行一个整数,表示此时所有冷饮店到仓库的距离之和
Sample Input 1
5
10
5
12
3
7
Sample Output 1
0
5
7
14
14
思路
举例可知,只用维护各个节点到中间节点的距离即可
难点:
1、如何快速计算距离
l维护左边的sum,r维护右边的sum,mid表示中位数
2、如何找中位数
对顶堆
代码
#include <bits/stdc++.h>
typedef long long LL;
using namespace std;
priority_queue<int> s; //大根堆
priority_queue<int, vector<int>, greater<int> > e; //小根堆
int n;
LL l, r;
int main()
{
scanf("%d", &n);
for (int i = 1; i <= n; i ++ )
{
int x;
scanf("%d", &x);
if (!e.size() || x > e.top())
{
e.push(x);
r += x;
}
else
{
s.push(x);
l += x;
}
if (s.size() > e.size() + 1) //调整堆
{
l -= s.top();
r += s.top();
e.push(s.top());
s.pop();
}
else if (e.size() > s.size() + 1)
{
l += e.top();
r -= e.top();
s.push(e.top());
e.pop();
}
LL mid = 0; //中位数
if (s.size() > e.size()) mid = s.top(); //左侧中位数被减后,要加上
else if (s.size() < e.size()) mid = -e.top(); //右侧中位数被加后,要减掉
printf("%lld\n", r - l + mid);
}
return 0;
}