# [NOI2016]区间(线段树+尺取法)

## 代码

//[NOI2016]区间
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define INF 0x3f3f3f3f
#define maxn 500000
using namespace std;
struct segment_tree{
struct node{
int l;
int r;
int val;
int mark;
int len(){
return r-l+1;
}
}tree[maxn*2*4+5];
void push_up(int pos){
tree[pos].val=max(tree[pos<<1].val,tree[pos<<1|1].val);//找到最大的覆盖次数
}
void build(int l,int r,int pos){
tree[pos].l=l;
tree[pos].r=r;
if(l==r) return;
int mid=(l+r)>>1;
build(l,mid,pos<<1);
build(mid+1,r,pos<<1|1);
push_up(pos);
}
void push_down(int pos){
if(tree[pos].mark){
tree[pos<<1].val+=tree[pos].mark;
tree[pos<<1].mark+=tree[pos].mark;
tree[pos<<1|1].val+=tree[pos].mark;
tree[pos<<1|1].mark+=tree[pos].mark;
tree[pos].mark=0;
}
}
void update(int L,int R,int val,int pos){
if(L<=tree[pos].l&&R>=tree[pos].r){
tree[pos].val+=val;
tree[pos].mark+=val;
return;
}
push_down(pos);
int mid=(tree[pos].l+tree[pos].r)>>1;
if(L<=mid) update(L,R,val,pos<<1);
if(R>mid) update(L,R,val,pos<<1|1);
push_up(pos);
}
int query_all(){
return tree[1].val;
}
}T;

int n,m;
struct seg{
int len;
int l;
int r;
friend bool operator < (seg p,seg q){
return p.len<q.len;
}
}a[maxn+5];
int tmp[maxn*2+5];
int dn=0;
int main(){
#ifndef LOCAL
freopen("interval.in","r",stdin);
freopen("interval.out","w",stdout);
#endif
scanf("%d %d",&n,&m);
for(int i=1;i<=n;i++){
scanf("%d %d",&a[i].l,&a[i].r);
tmp[++dn]=a[i].l;
tmp[++dn]=a[i].r;
a[i].len=a[i].r-a[i].l+1;
}
sort(tmp+1,tmp+1+dn);
dn=unique(tmp+1,tmp+1+dn)-tmp-1;
for(int i=1;i<=n;i++){
a[i].l=lower_bound(tmp+1,tmp+1+dn,a[i].l)-tmp;
a[i].r=lower_bound(tmp+1,tmp+1+dn,a[i].r)-tmp;
}
sort(a+1,a+1+n);
T.build(1,dn,1);
int ans=INF;
for(int i=1,j=1;i<=n;i++){
T.update(a[i].l,a[i].r,1,1);
while(T.query_all()>=m){
ans=min(ans,a[i].len-a[j].len);
T.update(a[j].l,a[j].r,-1,1);
j++;
}
}
if(ans==INF) printf("-1\n");
else printf("%d\n",ans);
}

posted @ 2020-12-03 16:04  birchtree  阅读(62)  评论(0编辑  收藏  举报