4653: [Noi2016]区间

Time Limit: 60 Sec  Memory Limit: 256 MB
Submit: 1593  Solved: 869
[Submit][Status][Discuss]

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
 
 

思路很神的乱搞题。

如果不管复杂度,我们可以考虑先将所有区间离散化,之后按照区间长度排序。然后从左往右扫,以每个区间为起始区间,尝试逐个加入之后的区间。怎么加入呢?用一个数组表示覆盖层数,将它左端点到右端点之间的所有点+1,表示多覆盖了一层。当有一个点被覆盖到m层时,统计一下目前的最靠右区间与起始区间的长度差更新答案。实际上,我们并不管具体选了哪些区间,只管能更新答案的最大长度的和最小长度的两个,这样只要保证选择合法即可,不用讨论具体选择。

(博主写到这里,冥思苦想40min,还是没证出来它的正确性,所以咕了)

(之后线段树优化一下区间加法就好了)

不要脸的博主又回来了。之前一直想不明白的原因在于纠结它会不会因为想找最优而漏解 导致输出-1的情况出错,这实际上是不可能的。如果你从左往右扫到n都没有更新答案,就说明确实没有方案可以满足一个点被覆盖m次,因为即使是单调指针 这么全扫一遍也能够考虑到所有情况。

至于线段树优化,其实就是用一个区间加法和全局最大值查询(所以没必要写区间查询的函数)。

#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
#define ls(k) k<<1
#define rs(k) k<<1|1
using namespace std;
int read()
{
int x=,f=;char ch=getchar();
while(ch<''||ch>''){if(ch=='-')f=-;ch=getchar();}
while(ch>=''&&ch<='')x=x*+ch-'',ch=getchar();
return x*f;
}
const int N=;
int n,m,c[N<<],tot,top,ans=0x3f3f3f3f;
struct node
{
int l,r,len;
}q[N];
int cmp(node x,node y)
{
return x.len<y.len;
}
int maxx[N<<],lz[N<<];
void down(int k,int l,int r)
{
if(l==r)
{
lz[k]=;
return ;
}
lz[ls(k)]+=lz[k];lz[rs(k)]+=lz[k];
maxx[ls(k)]+=lz[k];maxx[rs(k)]+=lz[k];
lz[k]=;
}
void add(int k,int l,int r,int L,int R,int val)
{
if(L<=l&&R>=r)
{
maxx[k]+=val;
lz[k]+=val;
return ;
}
int mid=l+r>>;
if(lz[k])down(k,l,r);
if(L<=mid)add(ls(k),l,mid,L,R,val);
if(R>mid)add(rs(k),mid+,r,L,R,val);
maxx[k]=max(maxx[ls(k)],maxx[rs(k)]);
}
int main()
{
n=read();m=read();
for(int i=;i<=n;i++)
q[i].l=read(),q[i].r=read(),q[i].len=q[i].r-q[i].l,c[++tot]=q[i].l,c[++tot]=q[i].r;
sort(c+,c+tot+);
tot=unique(c+,c+tot+)-c-;
for(int i=;i<=n;i++)
q[i].l=lower_bound(c+,c+tot+,q[i].l)-c,q[i].r=lower_bound(c+,c+tot+,q[i].r)-c;
sort(q+,q+n+,cmp);
for(int i=;i<=n;i++)
{
while(maxx[]<m&&top<n)
top++,add(,,tot,q[top].l,q[top].r,);
if(maxx[]==m)ans=min(ans,q[top].len-q[i].len);
add(,,tot,q[i].l,q[i].r,-);
}
if(ans==0x3f3f3f3f)puts("-1");
else cout<<ans<<endl;
return ;
}

[NOI2016]区间 题解(决策单调性+线段树优化)的更多相关文章

  1. 【题解】Journeys(线段树优化连边)

    [#3073. Pa2011]Journeys (线段树优化连边) 这张图太直观了,直接讲透了线段树优化连边的原理和正确性. 考虑建立两颗线段树,一颗是外向树,一颗是内向树,相当于网络流建模一样,我们 ...

  2. luogu P1712 [NOI2016]区间 贪心 尺取法 线段树 二分

    LINK:区间 没想到尺取法. 先说暴力 可以发现答案一定可以转换到端点处 所以在每个端点从小到大扫描线段就能得到答案 复杂度\(n\cdot m\) 再说我的做法 想到了二分 可以进行二分答案 从左 ...

  3. BZOJ 4653 [Noi2016]区间(Two pointers+线段树)

    [题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=4653 [题目大意] 在数轴上有n个闭区间 [l1,r1],[l2,r2],...,[l ...

  4. 【bzoj4383】[POI2015]Pustynia 线段树优化建图+差分约束系统+拓扑排序

    题目描述 给定一个长度为n的正整数序列a,每个数都在1到10^9范围内,告诉你其中s个数,并给出m条信息,每条信息包含三个数l,r,k以及接下来k个正整数,表示a[l],a[l+1],...,a[r- ...

  5. 炸弹:线段树优化建边+tarjan缩点+建反边+跑拓扑

    这道题我做了有半个月了...终于A了... 有图为证 一句话题解:二分LR线段树优化建边+tarjan缩点+建反边+跑拓扑统计答案 首先我们根据题意,判断出来要炸弹可以连着炸,就是这个炸弹能炸到的可以 ...

  6. CodeForces 558E(计数排序+线段树优化)

    题意:一个长度为n的字符串(只包含26个小字母)有q次操作 对于每次操作 给一个区间 和k k为1把该区间的字符不降序排序 k为0把该区间的字符不升序排序 求q次操作后所得字符串 思路: 该题数据规模 ...

  7. [bzoj3073] Journeys 题解(线段树优化建图)

    Description Seter建造了一个很大的星球,他准备建造N个国家和无数双向道路.N个国家很快建造好了,用1..N编号,但是他发现道路实在太多了,他要一条条建简直是不可能的!于是他以如下方式建 ...

  8. 7月13日考试 题解(DFS序+期望+线段树优化建图)

    T1 sign 题目大意:给出一棵 N 个节点的树,求所有起点为叶节点的有向路径,其 上每一条边权值和的和.N<=10000 水题.考试的时候毒瘤出题人(学长orz)把读入顺序改了一下,于是很多 ...

  9. SRM12 T2夏令营(分治优化DP+主席树 (已更新NKlogN)/ 线段树优化DP)

     先写出朴素的DP方程f[i][j]=f[k][j-1]+h[k+1][i] {k<i}(h表示[k+1,j]有几个不同的数)  显然时间空间复杂度都无法承受   仔细想想可以发现对于一个点 i ...

随机推荐

  1. paper 142:SDM算法--Supervised Descent Method

    对于face recognition的研究,我是认真的(认真expression,哈哈哈~~~~~~)许久没有写blog了,欢迎一起讨论. SDM(Supvised Descent Method)方法 ...

  2. CDN(Content Delivery Network)内容分发网络

    CDN的全称是Content Delivery Network,即内容分发网络.其基本思路是尽可能避开互联网上有可能影响数据传输速度和稳定性的瓶颈和环节,使内容传输的更快.更稳定.通过在网络各处放置节 ...

  3. [CSP-S模拟测试47]反思+题解

    打开题面,T3似乎被换过了.(那我就更有理由直接弃掉了) T1是我最害怕的乱搞题,赶紧扔了看T2.发现是个sb板子?雨天的尾巴弱化版? 然而线段树合并早忘干净了(最近几道可以线段树合并的题都是用别的方 ...

  4. Ubuntu安装可视化电脑配置视图工具neofetch

    安装步骤: sudo apt-get install software-properties-common python-software-propertiessudo add-apt-reposit ...

  5. java并发编程笔记(二)——并发工具

    java并发编程笔记(二)--并发工具 工具: Postman:http请求模拟工具 Apache Bench(AB):Apache附带的工具,测试网站性能 JMeter:Apache组织开发的压力测 ...

  6. vi总结的几个技巧

    1.用vi编辑完文件后 按两次Z可以直接保存退出2.在打开一个vi编辑时可以输入:sp /etc/passwd 同时打开另一个文件注意这里要用绝对路径

  7. 31. Git与Github

    Github介绍 GitHub是一个面向开源及私有软件项目的托管平台,因为只支持git 作为唯一的版本库格式进行托管,故名gitHub. GitHub于2008年4月10日正式上线,除了Git代码仓库 ...

  8. HDU1251-统计难题-map+输入

    Ignatius最近遇到一个难题,老师交给他很多单词(只有小写字母组成,不会有重复的单词出现),现在老师要他统计出以某个字符串为前缀的单词数量(单词本身也是自己的前缀). Input输入数据的第一部分 ...

  9. PHP CURL 模拟form表单上传遇到的小坑

    1:引用的时候 $parans ['img']=new \CURLFile($param); 传入的文件 在PHP版本5.5以上记得new CURLFile 不然会上传不成功 /** * http p ...

  10. js基本函数和基本方法

    日期时间函数(需要用变量调用): var b = new Date(); //获取当前时间 b.getTime() //获取时间戳 b.getFullYear() //获取年份 b.getMonth( ...