在计算机科学中,堆是一个专门的基于树的数据结构,它本质上是一个完全树。
堆的一些性质:在最小堆中,对于任何给定的结点 C,如果 P 是 C 的父结点,那么结点 P 的值小于或等于 C 的值。堆的“顶部”的结点称为根结点。
通常,我们可以用数组 h1,h2,......,hn 存储大小为 n 的堆,其中 hi 表示第 i 个结点的值。
根结点是第 1 个结点,第 i(2≤i≤n) 个结点的父结点是第 ⌊2i⌋ 个结点。
Alice 和 Bob 正在最小堆上玩游戏。
两人轮流移动,Alice 先移动。
在每个人的回合里,这个人可以选择一个没有孩子的结点,把这个结点从堆中移开,同时获得同等于这个结点的值的分数。
当堆空时,游戏结束。
假设两人都足够聪明,Alice 和 Bob 的最终得分会是多少?
输入格式:
输入的第一行包含整数 T(1≤T≤10000),表示测试用例的数量。
在每个测试用例中,第一行中有一个整数 n(1≤n≤100000),表示节点数。
在第二行中,有 n 个整数 h1,h2,......,hn,1≤hi≤109,h⌊2i⌋≤hi),表示每个节点的关键字。
保证 ∑n≤106。
输出格式:
对于每个测试用例,打印包含两个整数 A 和 B 的单行,表示 Alice 和 Bob 的最终得分。
输入样例:
1
3
1 2 3
输出样例:
4 2
#include <bits/stdc++.h>
#define int long long
using namespace std;
int x[1000010],y[1000010];
signed main()
{
int n,b=0,c=0,a;
cin>>n;
while(n--)
{
b=0;
c=0;
int sum=0,t=0,res=0;
cin>>a;
for(int i=0;i<a;i++)
{
cin>>x[i];
}
sort(x,x+a);
int q=0;
//cout<<x[0]<<"***\n";
for(int i=a-1;i>=0;i--)
{
if(q==1)
{
c+=x[i];
q=0;
}
else if(q==0)
{
b+=x[i];
q=1;
}
}
printf("%lld %lld\n",b,c);
}
return 0;
}