#include <bits/stdc++.h>
using namespace std;
const int N = 3E5 + 7;
int n, k, a[N], dp[N];
bool judge(int key)
{
int pre = 0;
for(int i = k;i <= n;i ++) {
int j = dp[i - k] + 1;
if(a[i] - a[j] <= key) pre = i;
dp[i] = pre;
}
return dp[n] == n;
}
int main()
{
scanf("%d%d",&n,&k);
for(int i = 1;i <= n;i ++) scanf("%d",&a[i]);
sort(a + 1, a + 1 + n);
int l = 0, r = a[n] - a[1];
while(l <= r) {
int m = (l + r) / 2;
if(judge(m)) r = m - 1;
else l = m + 1;
}
printf("%d\n", l);
return 0;
}
二分然后随便DP下,dp[i]表示1-i可满足要求的最接近i的位置,如果最后整段都满足要求一定有dp[n] == n;
转移为如果a[i] - a[dp[i-k]+1] <= key(当前二分的)值则1~i都满足要求,因为dp[i - k]位置之前的都满足要求了,所以两断连起来也满足,则完成转移。