题目
我的解法是用优先队列减少后面算最小的时候的复杂度。 重点在于模拟最小的差,于是把差全部push到优先队列里面,然后一个个“探头”,遇到不在里面的就pop掉这样可以简化成O(n),虽然看着还是两重循环。
#include <bits/stdc++.h>
#define int long long
#define CIO std::ios::sync_with_stdio(false)
#define rep(i, l, r) for (int i = l; i <= r; i++)
#define nep(i, r, l) for (int i = r; i >= l; i--)
#define pii pair<int,int>
using namespace std;
const int N=2e6+5;
int a[N];
int d[N];
priority_queue<pii,vector<pii>,greater<pii> > q;
int pqd[N];
void work(){
int n,k;
cin>>n>>k;
rep(i,1,n){
cin>>a[i];
}
sort(a+1,a+n+1);
d[1]=0;
rep(i,2,n){
d[i]=a[i]-a[i-1];
}
int cnt=0;
int sum=0,mi=0,xiao=INT_MAX,mii=INT_MAX;
rep(i,2,n-k){
q.push({d[i],i});
}
rep(i,2,k+1){
sum=a[i+n-k-1-1]-a[i-1];
q.push({d[i+n-k-1],i+n-k-1});
while (!q.empty()){
if (!(i<=q.top().second&&q.top().second<=i+n-k-1)){
q.pop();
}
else{
xiao=q.top().first;
break;
}
}
// cout<<sum<<" "<<xiao<<endl;
mii=min(mii,sum+xiao);
}
cout<<mii;
}
signed main(){
CIO;
work();
return 0;
}