【bzoj4653】[Noi2016]区间
来源:互联网 发布:linux locale命令 编辑:程序博客网 时间:2024/05/21 02:53
Description
在数轴上有 n个闭区间 [l1,r1],[l2,r2],…,[ln,rn]。现在要从中选出 m 个区间,使得这 m个区间共同包含至少一个位置。换句话说,就是使得存在一个 x,使得对于每一个被选中的区间 [li,ri],都有 li≤x≤ri。
对于一个合法的选取方案,它的花费为被选中的最长区间长度减去被选中的最短区间长度。区间 [li,ri] 的长度定义为 ri−li,即等于它的右端点的值减去左端点的值。
求所有合法方案中最小的花费。如果不存在合法的方案,输出 −1。
Input
第一行包含两个正整数 n,m用空格隔开,意义如上文所述。保证 1≤m≤n
接下来 n行,每行表示一个区间,包含用空格隔开的两个整数 li 和 ri 为该区间的左右端点。
N<=500000,M<=200000,0≤li≤ri≤10^9
Output
只有一行,包含一个正整数,即最小花费。
Sample Input
6 3
3 5
1 2
3 4
2 2
1 5
1 4
Sample Output
2
题解
把线段从小到大排序,一次加入线段树中,知道存在某一点被覆盖m条线段,然后从小的开始删,知道不满足为止,这时即找到了一组解,重复此操作即可。需要离散。
代码
#include<cstdio>#include<cstring>#include<iostream>#include<cmath>#include<algorithm>struct node1{int l,r,al,ar,len,id;}a[500005];struct node2{int a,l,r,id;}ls[1000005];int add[8000005],mx[8000005];int n,m,cnt;using namespace std;inline int read(){ int x=0;char ch=getchar(); while (ch<'0'||ch>'9') ch=getchar(); while (ch>='0'&&ch<='9') x=x*10+ch-'0',ch=getchar(); return x;}bool cmp1(node1 a,node1 b){return a.len<b.len;}bool cmp2(node2 a,node2 b){return a.a<b.a;}void pushdown(int p,int l,int r){ if (l==r) return; int mid=(l+r)>>1; add[p<<1]+=add[p];add[p<<1|1]+=add[p]; mx[p<<1]+=add[p];mx[p<<1|1]+=add[p]; add[p]=0;}void modify(int p,int l,int r,int x,int y,int z){ if (add[p]) pushdown(p,l,r); if (l==x&&r==y) { add[p]+=z; mx[p]+=z; return; } int mid=(l+r)>>1; if (y<=mid) modify(p<<1,l,mid,x,y,z); else if (x>mid) modify(p<<1|1,mid+1,r,x,y,z); else { modify(p<<1,l,mid,x,mid,z); modify(p<<1|1,mid+1,r,mid+1,y,z); } mx[p]=max(mx[p<<1],mx[p<<1|1]);}int main(){ n=read();m=read(); for (int i=1;i<=n;i++) { a[i].l=read();a[i].r=read();a[i].len=a[i].r-a[i].l; ls[++cnt].a=a[i].l; ls[cnt].l=1; ls[cnt].id=i; ls[++cnt].a=a[i].r; ls[cnt].r=1; ls[cnt].id=i; } sort(ls+1,ls+cnt+1,cmp2); int pre=-1,num=0; for (int i=1;i<=cnt;i++) { if (ls[i].a!=pre) pre=ls[i].a,num++; if (ls[i].l) a[ls[i].id].al=num; else a[ls[i].id].ar=num; } sort(a,a+n+1,cmp1); int st=1,ed=1,ans=2000000000; while (ed<=n) { while (mx[1]<m&&ed<=n) { modify(1,1,num,a[ed].al,a[ed].ar,1); ed++; } while (mx[1]>=m) { ans=min(ans,a[ed-1].len-a[st].len); modify(1,1,num,a[st].al,a[st].ar,-1); st++; } } if (ans==2000000000) puts("-1"); else cout<<ans; return 0;}
0 0
- BZOJ4653 [Noi2016]区间
- [NOI2016][bzoj4653]区间
- 【NOI2016】bzoj4653 区间
- bzoj4653 [Noi2016]区间
- BZOJ4653: [Noi2016]区间
- 【bzoj4653】[Noi2016]区间
- bzoj4653 [Noi2016]区间
- bzoj4653 [Noi2016]区间
- bzoj4653: [Noi2016]区间
- BZOJ4653——[Noi2016]区间
- [BZOJ4653][Noi2016]区间 线段树
- 【BZOJ4653】【NOI2016】区间 线段树
- 【Bzoj4653】区间
- NOI2016区间
- BZOJ4653 NOI2016DAY2T1区间 线段树
- 【线段树】[NOI2016]区间
- 【uoj222】 NOI2016—区间
- 4653: [Noi2016]区间
- django-celery beat报错 error pid
- 如何有效解决问题?
- 安装android sdk
- 七项安全对策实现服务器保护
- HBase的Hmaster、HRegionserver、Region、Hstore、memstore、HFile的关系
- 【bzoj4653】[Noi2016]区间
- Android上传项目到Github
- mybatis写无签证接口APP
- 机器学习和深度学习的最佳框架
- Gulp新手入门教程
- nodejs+socket.io实现校内局域网聊天室
- 莫比乌斯反演
- Set、Map、list的排序,应用及案例
- Leetcode 506(Java)