Analysis
k叉哈夫曼樹解析
這道題稍微還需要注意一點的就是最後還要求最長長度最短
這個其實就是在面對兩個權值相同的情況下,優先合併深度較小的點
Code
#include<bits/stdc++.h>
#define re register
#define in read()
using namespace std;
inline char nc(){
static char buf[100000],*p1=buf,*p2=buf;
return p1==p2&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++;
}
typedef long long ll;
inline ll read(){
char ch;int f=1;ll res=0;
while((ch=nc())<'0'||ch>'9') if(ch=='-') f=-1;
while(ch>='0'&&ch<='9'){
res=(res<<1)+(res<<3)+(ch^48);
ch=nc();
}
return f==1?res:-res;
}
struct node{
ll val,dep;
bool operator <(const node &a)const{
if(val==a.val) return dep>a.dep;
return val>a.val;
}
};
priority_queue<node> q;
const int N=1e5+10;
int n,K;
ll ans=0,ans2=0;
void work(){
while(n>1){
ll new_val=0,new_dep=0;
for(re int i=1;i<=K;++i){
node tmp=q.top();q.pop();
new_val+=tmp.val;
new_dep=max(new_dep,tmp.dep+1);
}
q.push((node){new_val,new_dep});
ans+=new_val;ans2=max(ans2,new_dep);
n-=(K-1);
}
return ;
}
int main(){
// freopen("data.in","r",stdin);
ll x;
n=in;K=in;
for(re int i=1;i<=n;++i) x=in,q.push((node){x,0});
int _left=(n-1)%(K-1);
if(_left){_left=K-1-_left;for(re int i=1;i<=_left;++i) q.push((node){0,0});}
work();
printf("%lld\n%lld",ans,ans2);
return 0;
}