BZOJ 4653: [Noi2016]区间
来源:互联网 发布:java多线程调用方法 编辑:程序博客网 时间:2024/05/16 18:37
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
3 5
1 2
3 4
2 2
1 5
1 4
Sample Output
2
【解题方法】
容易想到先按照区间的长度来排序之后,明显有单调性,要统计直接用双指针移动维护答案就好了。用线段树维护一下出现次数。
【AC 代码】
////Created by just_sort 2016/8/19//All Rights Reserved//#include <vector>#include <cstdio>#include <cstring>#include <iostream>#include <algorithm>using namespace std;const int maxn = 1000010;const int inf = 0x3fffffff;struct query{ int l,r,len; bool operator<(const query &rhs) const{ return len<rhs.len; }}q[maxn*2];struct node{ int l,r; int maxx,lazy;}Tree[maxn*4];vector<int>xs;void pushup(int rt){ Tree[rt].maxx=max(Tree[rt*2].maxx,Tree[rt*2+1].maxx);}void pushdown(int rt){ if(Tree[rt].lazy){ Tree[rt*2].lazy+=Tree[rt].lazy; Tree[rt*2+1].lazy+=Tree[rt].lazy; Tree[rt*2].maxx+=Tree[rt].lazy; Tree[rt*2+1].maxx+=Tree[rt].lazy; Tree[rt].lazy=0; }}void Build(int l,int r,int rt){ Tree[rt].l=l,Tree[rt].r=r; Tree[rt].lazy=0,Tree[rt].maxx=0; if(l==r) return ; int mid=(l+r)/2; Build(l,mid,rt*2); Build(mid+1,r,rt*2+1);}void update(int L,int R,int v,int rt){ if(L==Tree[rt].l&&Tree[rt].r==R){ Tree[rt].lazy+=v; Tree[rt].maxx+=v; return ; } pushdown(rt); int mid=(Tree[rt].l+Tree[rt].r)/2; if(R<=mid) update(L,R,v,rt*2); else if(L>mid) update(L,R,v,rt*2+1); else{ update(L,mid,v,rt*2); update(mid+1,R,v,rt*2+1); } pushup(rt);}int main(){ xs.clear(); int n,m; scanf("%d%d",&n,&m); for(int i=1; i<=n; i++){ scanf("%d%d",&q[i].l,&q[i].r); q[i].len=q[i].r-q[i].l; xs.push_back(q[i].l); xs.push_back(q[i].r); } sort(xs.begin(),xs.end()); xs.resize(unique(xs.begin(),xs.end())-xs.begin()); int key=xs.size(); for(int i=1; i<=n; i++){ q[i].l=lower_bound(xs.begin(),xs.end(),q[i].l)-xs.begin()+1; q[i].r=lower_bound(xs.begin(),xs.end(),q[i].r)-xs.begin()+1; } sort(q+1,q+n+1); //cout<<key<<endl; Build(1,key,1); //two pointers int ans=inf,i,j=0; for(i=1; i<=n; i++){ while(j<n&&Tree[1].maxx<m) j++,update(q[j].l,q[j].r,1,1); if(Tree[1].maxx>=m) ans = min(ans,q[j].len-q[i].len); else break; update(q[i].l,q[i].r,-1,1); } if(ans==inf) ans=-1; printf("%d\n",ans); return 0;}
0 0
- BZOJ 4653: [Noi2016]区间
- BZOJ 4653: [Noi2016]区间
- bzoj 4653 [Noi2016]区间
- bzoj 4653: [Noi2016]区间 线段树
- BZOJ 4653: [Noi2016]区间 线段树
- bzoj 4653: [Noi2016]区间 (线段树)
- bzoj 4653: [Noi2016]区间(尺取+线段树)
- 4653: [Noi2016]区间
- NOI2016区间
- 【线段树】[NOI2016]区间
- BZOJ4653 [Noi2016]区间
- 【uoj222】 NOI2016—区间
- [NOI2016][bzoj4653]区间
- 【NOI2016】bzoj4653 区间
- CJOJ P2298 【NOI2016】区间
- bzoj4653 [Noi2016]区间
- BZOJ4653: [Noi2016]区间
- 【bzoj4653】[Noi2016]区间
- Vagrant: 一致性开发环境创建利器
- Vive开发之VR射箭
- J2se源码剖析 基本数据类型Integer
- Linux之索引节点inode(index node)
- jvm 指令集代码
- BZOJ 4653: [Noi2016]区间
- BigDecimal使用技巧
- Linux之文件通配符
- 多线程——用创建线程的两种方式分别解决经典窗口卖票问题
- QQ聊天界面侧滑删除
- python linux上交互模式tab自动补全代码
- javaScript笔记(二十五) Cookie与存储
- asm (1) helloworld
- linux 批量创建用户和修改口令