题意:k叉哈夫曼树
题解:2叉哈夫曼树的做法我们知道后,k叉哈夫曼树就是每次找前k小的。但是现在的问题是可能有非满叉结点。考虑到非满叉结点一定是在最后一层,所以只需要补x个0即可。推一推知道是x = k - 1 - (n - 1) % (k - 1)。
#include<bits/stdc++.h>
#define ll long long
using namespace std;
struct Node{
ll val;
int dep;
};
priority_queue< Node > q;
bool operator < (const Node &a,const Node &b){
return a.val > b.val || (a.val == b.val && a.dep > b.dep);
}
int n,k,d;
Node nw;
ll tot,x,ans;
int main(){
freopen("in.txt","r",stdin);
freopen("out.txt","w",stdout);
scanf("%d%d", &n, &k);
for(int i = 1; i <= n; i++){
scanf("%lld", &x);
q.push((Node){x, 1});
}
int rem = 0;
if((n - 1) % (k - 1)){
rem = k - 1 - (n - 1) % (k - 1);
n += rem;
}
for(int i = 1; i <= rem; i++)
q.push((Node){0, 1});
/*for(int i = 1; i <= n; i++){
nw = q.top();
printf("%lld ", nw.val);
q.pop();
}*/
n = (n - 1) / (k - 1);
for(int i = 1; i <= n; i++){
tot = 0;d = 0;
for(int j = 1; j <= k; j++){
nw = q.top();
tot += nw.val;
d = max(d, nw.dep);
q.pop();
}
q.push((Node){tot, d + 1});
ans += tot;
}
printf("%lld\n%d\n", ans, q.top().dep - 1);
return 0;
}