链接
尺取法,先将区间按长度排序,再依次按序加入,线段树维护点的覆盖次数,若最大值 (geq m),则对 (l) 区间来说,(r) 区间是满足条件的且与它距离最小的区间,更新答案并 (l+1),依次求出每个区间的答案。
#include<bits/stdc++.h>
#define IL inline
#define LL long long
#define ls k<<1
#define rs k<<1|1
using namespace std;
const int N=1e6+3;
struct hh{
int l,r,len;
bool operator<(const hh &a) const{
return len>a.len;}
}a[N];
int n,m,num,b[N],ans=1e9;
IL int in(){
char c;int f=1;
while((c=getchar())<'0'||c>'9')
if(c=='-') f=-1;
int x=c-'0';
while((c=getchar())>='0'&&c<='9')
x=x*10+c-'0';
return x*f;
}
struct segment{
int Max[N<<2],add[N<<2];
IL void Add(int k,int v){Max[k]+=v,add[k]+=v;}
void mdy(int k,int l,int r,int ll,int rr,int v){
if(l>=ll&&r<=rr) return Add(k,v);
int mid=l+r>>1;
if(ll<=mid) mdy(ls,l,mid,ll,rr,v);
if(rr>mid) mdy(rs,mid+1,r,ll,rr,v);
Max[k]=max(Max[ls],Max[rs])+add[k];
}
}T;
int main()
{
int x,y,l=1,r=0;
n=in(),m=in();
for(int i=1;i<=n;++i)
b[++num]=x=in(),b[++num]=y=in(),
a[i]=(hh){x,y,y-x};
sort(b+1,b+num+1),num=unique(b+1,b+num+1)-b-1;
for(int i=1;i<=n;++i)
a[i].l=lower_bound(b+1,b+num+1,a[i].l)-b,
a[i].r=lower_bound(b+1,b+num+1,a[i].r)-b;
sort(a+1,a+n+1);
for(int r=1;r<=n;++r){
T.mdy(1,1,num,a[r].l,a[r].r,1);
while(l<=r&&T.Max[1]>=m)
ans=min(ans,a[l].len-a[r].len),
T.mdy(1,1,num,a[l].l,a[l].r,-1),++l;
}
if(ans!=1e9) printf("%d
",ans);
else puts("-1");
return 0;
}