对于任意的 1≤i,j≤n,i≠j,都有:si 不是 sj 的前缀 这就是说要用到哈夫曼树
题目还要保证最长的字符串长度最小,那么如果现在有两个权值相同的节点,我们应该优先选择深度较小的节点,因为我们如果选择了深度大的节点那么这个树的深度就会变长,我们选中深度较小的节点,那么我们深度较大的节点会在后面安排上,比当前选择优。
在用scanf printf 输入数据时一定要注意这个数时 long long 还是 int
在用scanf printf 输入数据时一定要注意这个数时 long long 还是 int
在用scanf printf 输入数据时一定要注意这个数时 long long 还是 int
在用scanf printf 输入数据时一定要注意这个数时 long long 还是 int
在使用结构体函数直接赋值时也要注意 { 0ll,0 } 0之后的 ll 一定不能忘记
在使用结构体函数直接赋值时也要注意 { 0ll,0 } 0之后的 ll 一定不能忘记
在使用结构体函数直接赋值时也要注意 { 0ll,0 } 0之后的 ll 一定不能忘记
#include<bits/stdc++.h>
#define pr printf
#define sc scanf
#define fur(i,a,b) for(int i = a; i<= b ;i++)
#define fdr(i,a,b) for(int i = a; i>= b ;i--)
using namespace std;
typedef long long ll;
const int N = 100000 + 5 ;
typedef pair<ll , int > PLI;
int n,k;
priority_queue< PLI, vector <PLI> ,greater <PLI> >q;
int main()
{
//freopen("in.txt","r",stdin);
scanf("%d %d",&n,&k);
for(int i = 0 ; i < n ; i++){
ll x;
scanf("%lld",&x);
q.push({x,0});
}
ll res = 0 , ma = 0 ;
while(( q.size() - 1) % (k - 1) !=0)
{
q.push({0ll,0});
}
while(q.size() > 1){
ll sum = 0 ;
int dep = 0;
for(int i = 0 ;i < k ;i++)
{
sum +=q.top().first;
dep = max(dep , q.top().second);
q.pop();
}
res += sum;
q.push( {sum, dep + 1});
}
printf("%lld\n%d",res,q.top().second);
return 0;
}



京公网安备 11010502036488号