在数轴上有NN 个闭区间 [l_1,r_1],[l_2,r_2],…,[l_n,r_n][l_1,r_1 ],[l_2 ,r_2 ],…,。现在要从中选出M 个区间,使得这M 个区间共同包含至少一个位置。换句话说,就是使得存在一个 x,使得对于每一个被选中的区间,都有 l_i≤x≤r_i 。
对于一个合法的选取方案,它的花费为被选中的最长区间长度减去被选中的最短区间长度。区间 的长度定义为r-l,即等于它的右端点的值减去左端点的值。
求所有合法方案中最小的花费。如果不存在合法的方案,输出-1−1 。
对于这个题目,很容易可以联想到线段树,因为他是对区间进行操作,那么每次覆盖就是对这一段区间+1,于是我们就这样加,加到最大值为m为止。
对于怎么找区间差最小,这里运用了尺取法的思想(大佬的博客),两个指针,根据排好的序进行移动。
最后,因为数据范围比较大,所以还需要离散化,我是手打的离散化,没有有STL的太多东西
完整代码如下:
#include <algorithm>
#include <iostream>
#include <cstdio>
using namespace std;
#define ll long long
const int N=10000010;
#define re register
#define gc getchar()
#define ll long long
#define il inline
il int read() {
re int x(0),f(1);
re char ch=gc;
while(ch<'0'||ch>'9') {
if(ch=='-') f=-1;
ch=gc;
}
while(ch>='0'&&ch<='9') {
x=(x<<1)+(x<<3)+(ch^48);
ch=gc;
}
return x*f;
}
int ma[N],ad[N];
namespace xds {
#define ls id<<1
#define rs id<<1|1
void pushup(int id) {
ma[id]=max(ma[ls],ma[rs]);
}
void pushdown(int id) {
if(ad[id]) {
ad[ls]+=ad[id];
ad[rs]+=ad[id];
ma[ls]+=ad[id];
ma[rs]+=ad[id];
ad[id]=0;
}
}
void change(int id,int l,int r,int L,int R,int val) {
if(l>=L&&r<=R) {
ma[id]+=val;
ad[id]+=val;
return;
}
pushdown(id);
int mid=(l+r)>>1;
if(mid>=L) change(ls,l,mid,L,R,val);
if(mid<R) change(rs,mid+1,r,L,R,val);
pushup(id);
}
}
struct node {
int l,r,len;
} e[N];
struct Node {
int v,id;
bool flag;
} c[N];
int n,m,cnt,tot;
bool cmp(node a,node b) {
return a.len==b.len?a.l<b.l:a.len<b.len;
}
bool Cmp(Node a,Node b) {
return a.v<b.v;
}
int main() {
n=read(),m=read();
for(int i=1; i<=n; ++i) {
e[i].l=read();
e[i].r=read();
e[i].len=e[i].r-e[i].l;
}
sort(e+1,e+1+n,cmp);
for(int i=1; i<=n; ++i) {
c[++cnt]=(Node) {
e[i].l,i,0
},
c[++cnt]=(Node) {
e[i].r,i,1
};
}
sort(c+1,c+1+cnt,Cmp);
c[0].v=-1;
for(int i=1; i<=cnt; ++i) {
if(c[i].v!=c[i-1].v) ++tot;
c[i].flag?e[c[i].id].r=tot:e[c[i].id].l=tot;
}
int last=1,ans=1e9;
for(int i=1; i<=n; ++i) {
xds::change(1,1,tot,e[i].l,e[i].r,1);
while(ma[1]>=m) {
xds::change(1,1,tot,e[last].l,e[last].r,-1);
ans=min(ans,e[i].len-e[last].len),++last;
}
}
if(ans==1e9) cout<<-1;
else cout<<ans;
return 0;
}