UOJ 222

http://uoj.ac/problem/222

对区间离散化

然后区间长度排序+双指针支取+标记永久化的线段树维护

#include<cstdio>
#include<algorithm>
#define FOR(i,s,t) for(register int i=s;i<=t;++i)
using namespace std;
const int N=1000011,inf=2147483647;
int ans,n,m;
struct qs{
    int l,r;
    inline bool operator<(qs A)const{return (r-l)<(A.r-A.l);}
}q[N];
int b[N<<1];
int tr[N<<2],ad[N<<2];
inline int max(int a,int b){return a>b?a:b;}
inline int min(int a,int b){return a<b?a:b;}
inline int d(int x,int y){return ((b[q[x].r]-b[q[x].l])-(b[q[y].r]-b[q[y].l]));}
inline void change(int k,int l,int r,int x,int y,int z){
	if(x<=l&&r<=y){
		tr[k]+=z,ad[k]+=z;
		return ;
	}
	int mid=(l+r)>>1;
	if(x<=mid)change(k<<1,l,mid,x,y,z);
	if(mid<y)change(k<<1|1,mid+1,r,x,y,z);
	tr[k]=max(tr[k<<1],tr[k<<1|1])+ad[k];
}
int main(){
	ans=inf;
    scanf("%d%d",&n,&m);
    FOR(i,1,n)scanf("%d%d",&q[i].l,&q[i].r),b[++b[0]]=q[i].l,b[++b[0]]=q[i].r;
    sort(b+1,b+b[0]+1);sort(q+1,q+n+1);
    b[0]=unique(b+1,b+b[0]+1)-b-1;
    FOR(i,1,n)
		q[i].l=lower_bound(b+1,b+b[0]+1,q[i].l)-b,
		q[i].r=lower_bound(b+1,b+b[0]+1,q[i].r)-b;
	for(register int l=1,r=1;l<=n;++l){
		while(r<=n&&tr[1]<m)change(1,1,b[0],q[r].l,q[r].r,1),++r;
		if(r>n&&tr[1]<m)break;
		ans=min(ans,d(r-1,l));
		change(1,1,b[0],q[l].l,q[l].r,-1);
	}
	printf("%d",ans==inf?-1:ans);
    return 0;
}

  

posted @ 2017-12-03 22:12  Stump  阅读(161)  评论(0编辑  收藏  举报