这题我们发现,只有在剩下的数是一段连续的数的时候才是最优的。
所以,这题我们用桶来做。
之前用线段树来做,结果T︿( ̄︶ ̄)︿了。。。
我们用桶维护区间最小值,然后在记录一下这个差值的位置。
不断地搞这东东就可以了。
上标:
#include<cstdio>
#include<algorithm>
#define N 1000010
using namespace std;
int n,K,a[N],d[N],fr[N],ans=(1<<30),tot=0;
inline int read()
{
int x=0,f=0; char c=getchar();
while (c<'0' || c>'9') f=(c=='-') ? 1:f,c=getchar();
while (c>='0' && c<='9') x=(x<<1)+(x<<3)+(c^48),c=getchar();
return f ? -x:x;
}
void up(int x)
{
while (x>1 && d[x]<d[x>>1])
swap(d[x],d[x>>1]),swap(fr[x],fr[x>>1]),x>>=1;
}
void down()
{
int x=1,t=x<<1;
if (d[t]>d[t+1] && t<tot) t++;
while (t<=tot)
{
if (d[t]<d[x])
swap(d[t],d[x]),swap(fr[t],fr[x]),x=t;
else break;
t=x<<1;
if (d[t]>d[t+1] && t<tot) t++;
}
}
int main()
{
n=read(),K=n-read();
for (int i=1;i<=n;i++) a[i]=read();
sort(a+1,a+n+1);
for (int i=2;i<=K;i++)
d[++tot]=a[i]-a[i-1],fr[tot]=i,up(tot);
ans=a[K]-a[1]+d[1];
for (int i=K+1;i<=n;i++)
{
d[++tot]=a[i]-a[i-1],fr[tot]=i,up(tot);
while (fr[1]<=i-K+1) d[1]=d[tot],fr[1]=fr[tot],tot--,down();
if (d[1]+a[i]-a[i-K+1]<ans) ans=d[1]+a[i]-a[i-K+1];
}
printf("%d
",ans);
return 0;
}