将所有区间按照长度排序,枚举最小长度和最大长度,然后判断区间内是否存在符合条件的m个区间
这个东西由于右端点单调递增,所以即:1.支持插入区间;2.支持删除区间;3.维护是否存在被m个区间覆盖的点
对于3操作,可以视为维护区间max,即区间加减和区间max,线段树即可
1 #include<bits/stdc++.h> 2 using namespace std; 3 #define N 500005 4 #define mid (l+r>>1) 5 struct ji{ 6 int l,r,len; 7 bool operator < (const ji &k)const{ 8 return len<k.len; 9 } 10 }a[N]; 11 int V,n,m,r,sum,ans,f[N*30],laz[N*30],ls[N*30],rs[N*30]; 12 void update(int &k,int l,int r,int x,int y,int z){ 13 if ((l>y)||(x>r))return; 14 if (!k)k=++V; 15 if ((x<=l)&&(r<=y)){ 16 f[k]+=z; 17 laz[k]+=z; 18 return; 19 } 20 update(ls[k],l,mid,x,y,z); 21 update(rs[k],mid+1,r,x,y,z); 22 f[k]=max(f[ls[k]],f[rs[k]])+laz[k]; 23 } 24 int main(){ 25 scanf("%d%d",&n,&m); 26 for(int i=1;i<=n;i++){ 27 scanf("%d%d",&a[i].l,&a[i].r); 28 a[i].len=a[i].r-a[i].l; 29 } 30 ans=0x3f3f3f3f; 31 sort(a+1,a+n+1); 32 for(int i=1,j=1;i<=n;i++){ 33 if ((i==1)||(a[i-1]<a[i])){ 34 for(;j<=n;j++){ 35 if ((f[r]>=m)&&((j==1)||(a[j-1]<a[j])))break; 36 update(r,0,1e9,a[j].l,a[j].r,1); 37 } 38 if (f[r]>=m)ans=min(ans,a[j-1].len-a[i].len); 39 } 40 update(r,0,1e9,a[i].l,a[i].r,-1); 41 } 42 if (ans==0x3f3f3f3f)ans=-1; 43 printf("%d",ans); 44 }