按区间长度从小到大排序,枚举最小的区间长度,去覆盖线段,直到存在一个点被覆盖了>=m次,此时的区间长度就是最大的,更新答案。然后删掉目前最小值,继续尝试。复杂度 O(nlogn)
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>
using namespace std;
#define ll long long
#define inf 0x3f3f3f3f
#define N 500010
inline char gc(){
static char buf[1<<16],*S,*T;
if(S==T){T=(S=buf)+fread(buf,1,1<<16,stdin);if(T==S) return EOF;}
return *S++;
}
inline int read(){
int x=0,f=1;char ch=gc();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=gc();}
while(ch>='0'&&ch<='9') x=x*10+ch-'0',ch=gc();
return x*f;
}
int n,m,aa[N<<1],tot=0,ans=inf;
struct node{
int cov,mx;
}tr[N<<3];
struct Lines{
int x,y,len;
friend bool operator<(Lines a,Lines b){return a.len<b.len;}
}a[N];
inline void pushup(int p){
tr[p].mx=max(tr[p<<1].mx,tr[p<<1|1].mx);
}
inline void docov(int p,int val){
tr[p].cov+=val;tr[p].mx+=val;
}
inline void pushdown(int p){
if(!tr[p].cov) return;docov(p<<1,tr[p].cov);docov(p<<1|1,tr[p].cov);tr[p].cov=0;
}
inline void cover(int p,int l,int r,int x,int y,int val){
if(x<=l&&r<=y){docov(p,val);return;}
int mid=l+r>>1;pushdown(p);
if(x<=mid) cover(p<<1,l,mid,x,y,val);
if(y>mid) cover(p<<1|1,mid+1,r,x,y,val);pushup(p);
}
int main(){
// freopen("a.in","r",stdin);
n=read();m=read();
for(int i=1;i<=n;++i) a[i].x=aa[++tot]=read(),a[i].y=aa[++tot]=read(),a[i].len=a[i].y-a[i].x;
sort(aa+1,aa+tot+1);tot=unique(aa+1,aa+tot+1)-aa-1;
for(int i=1;i<=n;++i){
a[i].x=lower_bound(aa+1,aa+tot+1,a[i].x)-aa;
a[i].y=lower_bound(aa+1,aa+tot+1,a[i].y)-aa;
}sort(a+1,a+n+1);int now=1;
for(int i=1;i<=n;++i){
while(tr[1].mx<m&&now<=n) cover(1,1,tot,a[now].x,a[now].y,1),++now;
if(tr[1].mx<m) break;ans=min(ans,a[now-1].len-a[i].len);
cover(1,1,tot,a[i].x,a[i].y,-1);
}if(ans==inf) puts("-1");
else printf("%d\n",ans);
return 0;
}