把区间按长度排序,我们发现对于每个区间,假设以其为最长区间,并保证当前存在一个点被m个区间覆盖的话,那么最短那个区间是不降的,所以我们排序后挨个进行区间+1操作,然后再维护一个指针代表当前的最短区间,指针往后扫同时进行区间-1操作直到当前最大值不大于m,期间更新答案,用一个线段树维护区间加和全局最大值即可
区间要离散化一下
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<ctime>
#include<cmath>
#include<algorithm>
#include<iomanip>
#include<bitset>
#include<set>
#include<map>
#include<vector>
#include<stack>
#include<queue>
using namespace std;
#define MAXN 500010
#define MAXM 1010
#define INF 1000000000
#define MOD 1000000007
#define eps 1e-8
#define ll long long
struct itv{
int l;
int r;
int len;
friend bool operator <(itv x,itv y){
return x.len<y.len;
}
};
int n,m;
int tls[MAXN*2],tln,mx;
itv a[MAXN];
map<int,int>h;
int v[MAXN<<3],ch[MAXN<<3];
int ans=INF*2;
inline void toch(int x,int y){
ch[x]+=y;
v[x]+=y;
}
inline void ud(int x){
v[x]=max(v[x<<1],v[x<<1|1]);
}
inline void pd(int x){
if(ch[x]){
toch(x<<1,ch[x]);
toch(x<<1|1,ch[x]);
ch[x]=0;
}
}
void change(int x,int y,int z,int l,int r,int cv){
if(y==l&&z==r){
toch(x,cv);
return ;
}
pd(x);
int mid=y+z>>1;
if(r<=mid){
change(x<<1,y,mid,l,r,cv);
}else if(l>mid){
change(x<<1|1,mid+1,z,l,r,cv);
}else{
change(x<<1,y,mid,l,mid,cv);
change(x<<1|1,mid+1,z,mid+1,r,cv);
}
ud(x);
}
int main(){
int i;
scanf("%d%d",&n,&m);
if(!m){
printf("0\n");
return 0;
}
for(i=1;i<=n;i++){
scanf("%d%d",&a[i].l,&a[i].r);
a[i].len=a[i].r-a[i].l;
tls[++tln]=a[i].l;
tls[++tln]=a[i].r;
}
sort(tls+1,tls+tln+1);
tls[0]=-INF;
for(i=1;i<=tln;i++){
if(tls[i]!=tls[i-1]){
h[tls[i]]=++mx;
}
}
for(i=1;i<=n;i++){
a[i].l=h[a[i].l];
a[i].r=h[a[i].r];
}
sort(a+1,a+n+1);
int wzh=1;
for(i=1;i<=n;i++){
change(1,1,mx,a[i].l,a[i].r,1);
while(v[1]>=m){
ans=min(ans,a[i].len-a[wzh].len);
change(1,1,mx,a[wzh].l,a[wzh].r,-1);
wzh++;
}
}
if(ans==INF*2){
ans=-1;
}
printf("%d\n",ans);
return 0;
}
/*
6 3
3 5
1 2
3 4
2 2
1 5
1 4
*/