荷马史诗
荷马史诗
题解
一道Huffman树的模板题。尽管笔者考试时未做出来(因为不会Huffman)。
其实到我们明白题意后就可以知道此题就是在一棵k叉树上旋n个点,使没有一个点的祖先被选。
研究到这里,很明显的一道Huffman的模板,至于Huffman具体怎么实现就不再说明了。
源码
//#pragma GCC optimize(3)
//#pragma GCC optimize(2)
#include<cstdio>
#include<cmath>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<queue>
#include<map>
#define MAXN 100005
using namespace std;
typedef long long LL;
#define gc() getchar()
template<typename _T>
inline void read(_T &x){
_T f=1;x=0;char s=gc();
while(s>'9'||s<'0'){if(s=='-')f=-1;s=gc();}
while(s>='0'&&s<='9'){x=(x<<3)+(x<<1)+(s^48);s=gc();}
x*=f;
}
struct ming{
LL val,dep;
ming(){val=dep=0;}
ming(LL V,LL D){
val=V;dep=D;
}
bool friend operator < (const ming &x,const ming &y){
if(x.val==y.val)return x.dep>y.dep;
return x.val>y.val;
}
};
int n,k;
LL w[MAXN],ans;
priority_queue<ming> q;
signed main() {
read(n);read(k);
for(int i=1;i<=n;i++)read(w[i]),q.push(ming(w[i],0));
while((n-1)%(k-1)!=0) n++,q.push(ming(0,0));
while(n>1){
LL sum=0,maxx=0;
for(int i=1;i<=k;i++){
ming t=q.top();q.pop();
maxx=max(maxx,t.dep);sum+=t.val;
}
q.push(ming(sum,maxx+1));
ans+=sum;n-=(k-1);
}
printf("%lld\n%lld",ans,q.top().dep);
//while(!q.empty())q.pop();
return 0;
}