维护一个数组里的连续K个里面的最大值和最小值,优先队列
//升序队列
priority_queue <int,vector<int>,greater<int> > q;
//降序队列
priority_queue <int,vector<int>,less<int> >q;
//greater和less是std实现的两个仿函数(就是使一个类的使用看上去像一个函数。其实现就是类中实现一个operator(),这个类就有了类似函数的行为,就是一个仿函数类了)
#include <bits/stdc++.h>
#define IOS ios::sync_with_stdio(false)
#define endl '\n'
using namespace std;
typedef long long ll;
const int N = 2e5 + 10;
ll T, n, k;
priority_queue<ll, vector<ll>, greater<ll> > pq; //维护升序
ll a[N];
signed main()
{
IOS; cin.tie(0), cout.tie(0);
cin >> T;
while (T--)
{
cin >> n >> k;
for (ll i = 1; i <= n; ++i)
{
cin >> a[i];
}
for (ll i = 1; i <= k; ++i) //先将前K个元素入队
{
pq.push(a[i]);
}
ll cha = 0;
ll temp = 2 * pq.top();
pq.pop();
cha = temp / 2;
for (ll i = k + 1; i <= n; ++i) //这一步就是对前K大的维护
{
pq.push(a[i]);
ll atemp = pq.top();
pq.pop();
if (temp >= atemp)
{
temp = temp + atemp;
}
else if (temp < atemp)
{
cha = cha + atemp - temp;
temp = 2 * atemp;
}
}
for (ll i = 1; i <= k - 1; ++i) //注意队列中还是有元素的,所以要把里面还剩下的k - 1个元素,继续处理
{
int atemp = pq.top();
pq.pop();
if (temp >= atemp)
{
temp = temp + atemp;
}
else if (temp < atemp)
{
cha = cha + atemp - temp;
temp = 2 * atemp;
}
}
cout << cha << endl;
}
return 0;
}