#include <cstdio>
#include <cstdlib>
#include <algorithm>
using namespace std;
#define min(a,b) ( (a)< (b)? (a): (b) )
int n, m;
int const N= 400100;
typedef long long LL;
/*
dp[i]= min{ dp[j]+ sum[i]- sum[j]+ ( i- j )* data[j+ 1] }
要求分段的序列长度不小于 m,即 i- j+ 1>= m
假设 j> k, 要使决策 j 比决策 k 优, 则有
dp[j]+ sum[i]- sum[j]+ ( i- j )* data[j+ 1]<
dp[k]+ sum[i]- sum[k]+ ( i- k )* data[k+ 1]
整理有:
dp[j]- sum[j]- j* data[j+ 1]- ( dp[k]- sum[k]- k* data[k+ 1] )
< i* ( data[j+ 1]- data[k+ 1] )
所以 j 比 k 优等价于
( dp[j]- dp[k]- sum[j]+ sum[k]- j* data[j+ 1]+ k* data[k+ 1] )/
( data[j+ 1]- data[k+ 1] )< i
今 F[j,k]= 上式左边
对于 k< j< i< t
假设 F[j, k]> F[i, j]
如果 F[i, j]< t 则 i 比 j 优
如果 F[i, j]> t 则 F[j, k]> t 得到 k 比 j 优
故对于满足条件 F[j,k]> F[i,j] 的可以剔除 j 状态
因为长度要不小于 2* m 故 1到 m- 1 都不可能成为决策点
对于 i, 能成为 i 状态的决策点的最小 j 为 i- m+ 1,并且对于
t> i, 这个最小 j= i- m+ 1 也有可能成为 t 的决策点
故对于当前状态 i ( i- m+ 1>= m ) 将决策点 i- m+ 1 加入
*/
LL dp[N], data[N], sum[N];
int que[N], head, tail;
inline LL S( int j, int k ){
return data[j+ 1]- data[k+ 1];
}
inline LL G( int j, int k ){
return dp[j]- sum[j]+ j* data[j+ 1]-
( dp[k]- sum[k]+ k* data[k+ 1] );
}
int main(){
while( scanf("%d%d",&n,&m)!= EOF ){
sum[0]= 0;
for( int i= 1; i<= n; ++i )scanf("%I64d", data+ i );
sort( data+ 1, data+ 1+ n );
for( int i= 1; i<= n; ++i )sum[i]= sum[i-1]+ data[i];
head= 0, tail= 0;
que[++tail]= 0; dp[0]= 0;
for( int i= m; i<= n; ++i ){
while( head< tail && S(que[head+ 1],que[head])* i>= G( que[head+ 1], que[head] ) )
head++;
dp[i]= dp[ que[head] ]+ ( sum[i]-sum[que[head]] )- ( i- que[head] )* data[ que[head]+ 1 ];
if( i- m+ 1>= m ) que[++tail]= i- m+ 1;
int j= que[tail]; tail--;
while( head< tail && G( que[tail], que[tail-1] )* S( j, que[tail] )>=
G( j, que[tail] )* S( que[tail], que[tail-1] ) ) tail--;
que[++tail]= j;
}
printf("%I64d\n", dp[n] );
}
return 0;
}