线段树 + 双指针
首先,将区间的端点离散化,并且将区间按长度排序,使得我们连续选的若干个区间最长与最短的长度相差最小
接着,我们用双指针寻找长度为 m m m 的区间集合( m m m 个区间),当区间被选中时,将它所覆盖的地方区间加一,取消选中时减一。如果有任意一个位置被覆盖了 x x x 次,说明这是有 x x x 个区间公共点;每次询问所有位置被标记次数的最大值 m a x v maxv maxv,如果 m a x v = m maxv=m maxv=m 则更新答案
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<map>
#include<queue>
using namespace std;
const long long Maxn=500000+100,inf=(1ll<<60);
const long long Maxm=Maxn<<3;
long long maxv[Maxm],add[Maxm];
long long c[Maxm];
long long n,m,tot,ans=inf;
map <long long , long long> id;
struct node{
long long l,r,len;
}a[Maxn];
inline bool cmp(node x,node y)
{
return x.len<y.len;
}
inline long long read()
{
long long s=0,w=1;
char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')w=-1;ch=getchar();}
while(ch>='0' && ch<='9')s=(s<<3)+(s<<1)+(ch^48),ch=getchar();
return s*w;
}
inline void push_up(long long k)
{
maxv[k]=max(maxv[k<<1],maxv[k<<1|1]);
}
inline void upd(long long k,long long v)
{
add[k]+=v;
maxv[k]+=v;
}
inline void push_down(long long k)
{
if(!add[k])return;
upd(k<<1,add[k]);
upd(k<<1|1,add[k]);
add[k]=0;
}
void modify(long long k,long long l,long long r,long long x,long long y,long long v)
{
if(x<=l && r<=y)return upd(k,v);
push_down(k);
long long mid=(l+r)>>1;
if(x<=mid)modify(k<<1,l,mid,x,y,v);
if(mid<y)modify(k<<1|1,mid+1,r,x,y,v);
push_up(k);
}
long long query(long long k,long long l,long long r,long long x,long long y)
{
if(x<=l && r<=y)return maxv[k];
push_down(k);
long long mid=(l+r)>>1,ret=0;
if(x<=mid)ret=query(k<<1,l,mid,x,y);
if(mid<y)ret=max(ret,query(k<<1|1,mid+1,r,x,y));
return ret;
}
int main()
{
// freopen("in.txt","r",stdin);
n=read(),m=read();
for(long long i=1;i<=n;++i)
{
a[i].l=read(),a[i].r=read();
a[i].len=a[i].r-a[i].l;
c[++tot]=a[i].l,c[++tot]=a[i].r;
}
sort(c+1,c+1+tot);
tot=0;
for(long long i=1;i<=(n<<1);++i)
if(!id[c[i]])id[c[i]]=++tot;
for(long long i=1;i<=n;++i)
{
a[i].l=id[a[i].l];
a[i].r=id[a[i].r];
}
sort(a+1,a+1+n,cmp);
long long l=1,r=0;
while(r<n)
{
while(r<n && maxv[1]<m)
{
++r;
modify(1,1,tot,a[r].l,a[r].r,1);
}
if(maxv[1]<m)continue;
while(l<=r && maxv[1]>=m)
{
ans=min(ans,a[r].len-a[l].len);
modify(1,1,tot,a[l].l,a[l].r,-1);
++l;
}
}
if(ans==inf)puts("-1");
else printf("%lld\n",ans);
return 0;
}