【题目链接】 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+线段树)的更多相关文章

  1. BZOJ.4653.[NOI2016]区间(线段树)

    BZOJ4653 UOJ222 考虑二分.那么我们可以按区间长度从小到大枚举每个区间,对每个区间可以得到一个可用区间长度范围. 我们要求是否存在一个点被这些区间覆盖至少\(m\)次.这可以用线段树区间 ...

  2. 【BZOJ4653】[Noi2016]区间 双指针法+线段树

    [BZOJ4653][Noi2016]区间 Description 在数轴上有 n个闭区间 [l1,r1],[l2,r2],...,[ln,rn].现在要从中选出 m 个区间,使得这 m个区间共同包含 ...

  3. 洛谷P1712 [NOI2016]区间 尺取法+线段树+离散化

    洛谷P1712 [NOI2016]区间 noi2016第一题(大概是签到题吧,可我还是不会) 链接在这里 题面可以看链接: 先看题意 这么大的l,r,先来个离散化 很容易,我们可以想到一个结论 假设一 ...

  4. bzoj 4653: [Noi2016]区间

    Description 在数轴上有 n个闭区间 [l1,r1],[l2,r2],...,[ln,rn].现在要从中选出 m 个区间,使得这 m个区间共同包含至少一个位置.换句话说,就是使得存在一个 x ...

  5. NOI2016区间bzoj4653(线段树,尺取法,区间离散化)

    题目描述 在数轴上有 \(N\) 个闭区间 \([l_1,r_1],[l_2,r_2],...,[l_n,r_n]\) .现在要从中选出 \(M\) 个区间,使得这 \(M\) 个区间共同包含至少一个 ...

  6. BZOJ 4653: [Noi2016]区间 双指针 + 线段树

    只要一堆线段有重叠次数大于等于 $m$ 次的位置,那么一定有解 因为重叠 $m$ 次只需 $m$ 个线断,将那些多余的线断排除掉即可 先将区间按照长度从小到大排序,再用 $two-pointer$ 从 ...

  7. 洛谷 1712 BZOJ 4653 [NOI2016]区间

    [题解] 先把区间按照未离散化的长度排序,保存区间长度,然后离散化区间端点.每次把区间覆盖的点的覆盖次数加1,如果某个点被覆盖次数大于等于m,就从前往后开始删除区间直到没有一个点被覆盖的次数大于等于m ...

  8. 线段树:CDOJ1597-An easy problem C(区间更新的线段树)

    An easy problem C Time Limit: 4000/2000MS (Java/Others) Memory Limit: 65535/65535KB (Java/Others) Pr ...

  9. BZOJ 2752 [HAOI2012]高速公路(road):线段树【维护区间内子串和】

    题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=2752 题意: 有一个初始全为0的,长度为n的序列a. 有两种操作: (1)C l r v: ...

随机推荐

  1. 【转载】Quick-Cocos2d-x文件结构分析

    在上一章我们讲过了Quick-Cocos2d-x中的环境搭建,这章我们分析下quick中的文件结构吧!打开quick的文件夹,可以看到如下的这些目录和文件: bin:存放各种与引擎相关的脚本 comp ...

  2. [IOS]vmxsmc.exe已停止工作 VMware11 Unlocker for Mac OSX无法使用的解决办法.

    今天我帮同事安装VMware workstation12后发现之前的unlocker已经无法进行解锁了(就是VMware新建虚拟机无App Mac选项) 使用unlocker会出现vmsxmc.exe ...

  3. jq_常用开发模块

    1.循环模块 var html = ""; $.each(data, function(k, v) { html += '<li>' + '<div>' + ...

  4. highcharts 从后台动态改变数据

    //columnChart    图表对象,创建示例就展示了. var series = this.columnChart.series;                            whi ...

  5. 空间数据库系列一:geomesa&sparksql 分析环境搭建

    geomesa sparksql 分析环境搭建 1.安装hbase-1.3.2.1 standlone版本,作为geomesa的store a.修改配置文件:hbase-1.3.2.1/conf/hb ...

  6. ubuntu tomcat的安装与配置

    一.下载jdk 大概是tomat大部分是由java写的, 所以一开始安装tomcat必须得配置好jdk http://www.oracle.com/technetwork/java/javase/do ...

  7. 【bzoj4459】JSOI2013丢番图

    某JSOI夏令营出题人啊,naive! 你还是得学习个,搬这种原题不得被我一眼看穿? 求个n^2的约数除以二,向上取整. #include<bits/stdc++.h> using nam ...

  8. C中级 MariaDB Connector/C API 编程教程

    引言 - 环境搭建 首先开始环境搭建. 主要在Window 10 + Visual Studio 2015 上构建使用 mariadb connector/c api 进行数据操作开发. 为什么选择在 ...

  9. Linux操作系统中内存buffer和cache的区别--从free命令说起(转)

    原文链接:http://os.51cto.com/art/200709/56603.htm 我们一开始,先从Free命令说起. Free free 命令相对于top 提供了更简洁的查看系统内存使用情况 ...

  10. 堆--LogN的数据结构

    我们这里的堆是指用来表示元素集合的一种数据结构 一个二叉树是一个堆是由堆的两个性质决定的(以小根堆为例) 1:任何节点的值都小于或等于其子节点的值 2:该二叉树最多在两层上具有叶节点,其中最底层的叶节 ...