BZOJ 4653 [Noi2016]区间(Two pointers+线段树)
【题目链接】 http://www.lydsy.com/JudgeOnline/problem.php?id=4653
【题目大意】
在数轴上有n个闭区间 [l1,r1],[l2,r2],...,[ln,rn]。
现在要从中选出m个区间,使得这m个区间共同包含至少一个位置。
对于一个合法的选取方案,它的花费为被选中的最长区间长度减去被选中的最短区间长度。
区间[li,ri]的长度定义为它的右端点的值减去左端点的值。
求所有合法方案中最小的花费。如果不存在合法的方案,输出-1。
【题解】
我们将所有的区间按照长度从小到大排序,那么我们枚举左端点和右端点,
将区间内的所有区间在线段树上更新1,
那么当有个点被覆盖m次的时候这个区间就可以用来更新答案,该操作只要求最大值即可。
区间的最大值对于左右端点的枚举具有单调性,
可以用Twopointers来实现,前后指针各移动n次,
复杂度O(nlogn)。
【代码】
#include <cstdio>
#include <algorithm>
#include <cstring>
using namespace std;
const int N=2000000;
struct node{int l,r,a,b,tag,max;}T[N];
const int INF=0x3f3f3f3f;
int tot,n,m,l,r,c;
void addtag(int x,int tag){
T[x].tag+=tag;
T[x].max+=tag;
}
void pb(int x){
if(T[x].l){addtag(T[x].l,T[x].tag);addtag(T[x].r,T[x].tag);}
T[x].tag=0;
}
void up(int x){T[x].max=max(T[T[x].l].max,T[T[x].r].max);}
void build(int l,int r){
int x=++tot;
T[x].a=l;T[x].b=r;T[x].tag=T[x].l=T[x].r=T[x].max=0;
if(l==r)return;
int mid=(l+r)>>1;
T[x].l=tot+1;build(l,mid);
T[x].r=tot+1;build(mid+1,r);
up(x);
}
void change(int x,int a,int b,int p){
if(T[x].a>=a&&T[x].b<=b){addtag(x,p);return;}
if(T[x].tag)pb(x); int mid=(T[x].a+T[x].b)>>1;
if(mid>=a&&T[x].l)change(T[x].l,a,b,p);
if(mid<b&&T[x].r)change(T[x].r,a,b,p);up(x);
}
int cnt,disc[N<<1];
struct data{int l,r,len;}p[N];
bool cmp(data a,data b){return a.len<b.len;}
int main(){
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++){
scanf("%d%d",&p[i].l,&p[i].r); p[i].len=p[i].r-p[i].l;
disc[++cnt]=p[i].l; disc[++cnt]=p[i].r;
}sort(disc+1,disc+cnt+1);
cnt=unique(disc+1,disc+cnt+1)-disc-1;
build(1,cnt);
for(int i=1;i<=n;i++){
p[i].l=lower_bound(disc+1,disc+cnt+1,p[i].l)-disc;
p[i].r=lower_bound(disc+1,disc+cnt+1,p[i].r)-disc;
}sort(p+1,p+n+1,cmp); int pt=0,ans=INF;
for(int i=1;i<=n;i++){
while(T[1].max<m&&pt<n){
pt++; change(1,p[pt].l,p[pt].r,1);
}if(T[1].max==m)ans=min(ans,p[pt].len-p[i].len);
change(1,p[i].l,p[i].r,-1);
}if(ans==INF)puts("-1");
else printf("%d\n",ans);
return 0;
}
BZOJ 4653 [Noi2016]区间(Two pointers+线段树)的更多相关文章
- BZOJ.4653.[NOI2016]区间(线段树)
BZOJ4653 UOJ222 考虑二分.那么我们可以按区间长度从小到大枚举每个区间,对每个区间可以得到一个可用区间长度范围. 我们要求是否存在一个点被这些区间覆盖至少\(m\)次.这可以用线段树区间 ...
- 【BZOJ4653】[Noi2016]区间 双指针法+线段树
[BZOJ4653][Noi2016]区间 Description 在数轴上有 n个闭区间 [l1,r1],[l2,r2],...,[ln,rn].现在要从中选出 m 个区间,使得这 m个区间共同包含 ...
- 洛谷P1712 [NOI2016]区间 尺取法+线段树+离散化
洛谷P1712 [NOI2016]区间 noi2016第一题(大概是签到题吧,可我还是不会) 链接在这里 题面可以看链接: 先看题意 这么大的l,r,先来个离散化 很容易,我们可以想到一个结论 假设一 ...
- bzoj 4653: [Noi2016]区间
Description 在数轴上有 n个闭区间 [l1,r1],[l2,r2],...,[ln,rn].现在要从中选出 m 个区间,使得这 m个区间共同包含至少一个位置.换句话说,就是使得存在一个 x ...
- NOI2016区间bzoj4653(线段树,尺取法,区间离散化)
题目描述 在数轴上有 \(N\) 个闭区间 \([l_1,r_1],[l_2,r_2],...,[l_n,r_n]\) .现在要从中选出 \(M\) 个区间,使得这 \(M\) 个区间共同包含至少一个 ...
- BZOJ 4653: [Noi2016]区间 双指针 + 线段树
只要一堆线段有重叠次数大于等于 $m$ 次的位置,那么一定有解 因为重叠 $m$ 次只需 $m$ 个线断,将那些多余的线断排除掉即可 先将区间按照长度从小到大排序,再用 $two-pointer$ 从 ...
- 洛谷 1712 BZOJ 4653 [NOI2016]区间
[题解] 先把区间按照未离散化的长度排序,保存区间长度,然后离散化区间端点.每次把区间覆盖的点的覆盖次数加1,如果某个点被覆盖次数大于等于m,就从前往后开始删除区间直到没有一个点被覆盖的次数大于等于m ...
- 线段树:CDOJ1597-An easy problem C(区间更新的线段树)
An easy problem C Time Limit: 4000/2000MS (Java/Others) Memory Limit: 65535/65535KB (Java/Others) Pr ...
- BZOJ 2752 [HAOI2012]高速公路(road):线段树【维护区间内子串和】
题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=2752 题意: 有一个初始全为0的,长度为n的序列a. 有两种操作: (1)C l r v: ...
随机推荐
- bzoj 1030 ac自动机
比较容易看出来先建立ac自动机,然后在自动机上做DP,设w[0..1][i][j]为当前不包括/包括字典中的字符串,当前在自动机中走到第i个节点,完成的文本的长度为j的方案数,那么比较容易的转移w[i ...
- Chrome 浏览器 autocomplete off无效
在表单填写时突然发现autocomplete 失效了 网上搜索后得出大概意思是在某些情况下确实无效[捂脸] 解决方案 大致原因是浏览器默认为type为password的input标签自动填充密码 这样 ...
- 多github帐号的SSH key切换
我有两个github帐号,一个是个人所用,一个是为公司项目所用.如果是单用户(single-user),很方便,默认拿id_rsa与你的github服务器的公钥对比:如果是多用户(multi-user ...
- Python模块学习 - Functools
Functools模块 Higher-order functions and operations on callable objects,看这个标题我都是懵逼的,这都是啥啥啥啊,赶紧拿出百度翻译:可 ...
- Linux进程调度与源码分析(一)——简介
本系列文章主要是近期针对Linux进程调度源码进行阅读与分析后的经验总结,分析过程中可能结合部分Linux网络编程的相关知识以便于理解,加深对Linux进程调度的理解和知识分享. 本系列文章主要结合L ...
- 过渡&动画
进入/离开&列表过渡 概述 Vue在插入,更新或者移除Dom时,提供多种不同方式的应用过渡效果.包括以下工具 在css过渡和动画中自动应用class 可以配合使用第三方css动画库,如Anim ...
- Go语言大神亲述:历七劫方可成为程序员!
“历劫1”:你坚信你可以用Go来做面向对象编程? 在经历了一次Go应用之旅之后,你可能就会开始思考:“怎么样才能让这种语言更像面向对象的编程语言?”因为你已经习惯了这种编程,你想要制作健壮的代码.想要 ...
- FineReport——FS
FR除了能够实现对报表等的二次开发,还能实现对决策系统的操作: FS.Trans.signOut() 退出决策平台系统 FS.tabPane._doCloseTab(FS.tabPane._getSe ...
- 创建数据库表的SQL语句
创建表.视图.索引的sql语句如下: CREAT TABLE (列名,数据类型,约束) create view(创建视图) create index (创建索引) 1.primary key(主键) ...
- 刷题中熟悉Shell命令之Tenth Line和Transpose File [leetcode]
首先介绍题目中要用的4个Shell命令 sed awk head tail的常用方法.(打好地基,才能建成高楼!) sed:(转自:http://www.cnblogs.com/barrychiao/ ...