【BZOJ4653】【Noi2016D2】区间
Description
在数轴上有 n个闭区间 [l1,r1],[l2,r2],...,[ln,rn]。现在要从中选出 m 个区间,使得这 m个区间共同包含至少一个位置。换句话说,就是使得存在一个 x,使得对于每一个被选中的区间 [li,ri],都有 li≤x≤ri。
对于一个合法的选取方案,它的花费为被选中的最长区间长度减去被选中的最短区间长度。区间 [li,ri] 的长度定义为 ri−li,即等于它的右端点的值减去左端点的值。
求所有合法方案中最小的花费。如果不存在合法的方案,输出 −1。
Input
第一行包含两个正整数 n,m用空格隔开,意义如上文所述。
接下来 n行,每行表示一个区间,包含用空格隔开的两个整数 li 和 ri 为该区间的左右端点。
Output
只有一行,包含一个正整数,即最小花费。
Sample Input
6 3
3 5
1 2
3 4
2 2
1 5
1 4
Sample Output
2
Hint
保证 1≤m≤n,N<=500000,M<=200000,0≤li≤ri≤10^9
Time Limit : 3s ,Memory Limit: 256MB.
Solution
首先考虑如何处理区间共同包含至少一个位置这一问题,显然可以利用线段树来解决,由于区间范围较大,因此需要离散后处理。
接下来考虑最长区间长度减去选中的最短区间长度,并且挑选m个,这一问题,根据最长-最短这一性质,以及数据范围,容易推断出将区间按长度排序后,利用头尾指针进行维护,将其间的所有区间加入线段树,只需要判断是否存在点被覆盖不少于m次的情况即可。
时间效率$ O(n \log_{2} n) $.
Code
#include <stdio.h>
#include <algorithm>
#define MN 500005
#define M (1<<20)
#define R register
#define mid (l+r>>1)
#define inf 0x3f3f3f3f
#define max(a,b) ((a)>(b)?(a):(b))
#define min(a,b) ((a)<(b)?(a):(b))
inline int read(){
R int x; R bool f; R char c;
for (f=0; (c=getchar())<'0'||c>'9'; f=c=='-');
for (x=c-'0'; (c=getchar())>='0'&&c<='9'; x=(x<<3)+(x<<1)+c-'0');
return f?-x:x;
}
int l[MN],r[MN],len[MN],T[M<<1],mark[M<<1],m,n,rk[MN],val[MN<<1],cnt=1,ans=inf;
inline bool cmp(int a,int b){return len[a]>len[b];}
inline int findpos(int k){
R int l=1,r=cnt; while(l<r)
if (val[mid]<k) l=mid+1;
else r=mid; return l;
}
inline void add(int k,int p){T[k]+=p,mark[k]+=p;}
inline void pushdown(int k){if (!mark[k]) return;add(k<<1,mark[k]);add(k<<1|1,mark[k]);mark[k]=0;}
inline void modify(int k,int l,int r,int a,int b,int ad){
if (l>=a&&r<=b) {add(k,ad); return;};pushdown(k);
if (a<=mid) modify(k<<1,l,mid,a,b,ad);
if (b>mid) modify(k<<1|1,mid+1,r,a,b,ad);
T[k]=max(T[k<<1],T[k<<1|1]);
}
int main(){
n=read(),m=read();
for (R int i=1; i<=n; ++i) l[i]=read(),r[i]=read(),len[i]=r[i]-l[i],rk[i]=i,val[(i-1)<<1|1]=l[i],val[i<<1]=r[i];
std::sort(val+1,val+(n<<1)+1);std::sort(rk+1,rk+n+1,cmp);
for (R int i=2; i<=(n<<1); ++i) if (val[i]!=val[i-1]) val[++cnt]=val[i];
for (R int i=1; i<=n; ++i) l[i]=findpos(l[i]),r[i]=findpos(r[i]);
for (R int h=1,t=1; t<=n; ++t)
for (modify(1,1,cnt,l[rk[t]],r[rk[t]],1); T[1]>=m; ans=min(ans,len[rk[h]]-len[rk[t]]),modify(1,1,cnt,l[rk[h]],r[rk[h++]],-1));
printf("%d\n",(ans==inf)?-1:ans);return 0;
}
【BZOJ4653】【Noi2016D2】区间的更多相关文章
- 【BZOJ-4653】区间 线段树 + 排序 + 离散化
4653: [Noi2016]区间 Time Limit: 60 Sec Memory Limit: 256 MBSubmit: 107 Solved: 70[Submit][Status][Di ...
- BZOJ4653: [Noi2016]区间
传送门 UOJ上卡掉一个点,COGS上卡掉两个点..弃疗,不改了,反正BZOJ上过啦hhh 先把区间按长度递增排序.然后每次用线段树维护区间最大覆盖次数,用一个指针随便扫扫就行了. //NOI 201 ...
- BZOJ4653 [NOI2016] 区间 【线段树】
题目分析: 首先思考一个二分答案的做法.我们可以注意到答案具有单调性,所以可以二分答案. 假设当前二分的答案是$ k $.那么按照大小顺序插入每个区间,同时在末端删除会对答案产生影响的区间.这里不妨用 ...
- 2018.08.17 bzoj4653: [Noi2016]区间(线段树+尺取法)
传送门 将坐标离散化之后直接用尺取法(双指针)+线段树维护. 其实就是说只要目前所有点的被覆盖次数是大于等于m的就移动左指针删除区间更新答案,否则移动右指针加入区间更新答案. 话说忘记排序以及建树的时 ...
- BZOJ4653:[NOI2016]区间(线段树)
Description 在数轴上有 n个闭区间 [l1,r1],[l2,r2],...,[ln,rn].现在要从中选出 m 个区间,使得这 m个区间共同包含至少一个位置.换句话说,就是使得存在一个 x ...
- [BZOJ4653][NOI2016]区间 贪心+线段树
4653: [Noi2016]区间 Time Limit: 60 Sec Memory Limit: 256 MB Description 在数轴上有 n个闭区间 [l1,r1],[l2,r2],. ...
- BZOJ4653 [NOI2016]区间 [线段树,离散化]
题目传送门 区间 Description 在数轴上有 n个闭区间 [l1,r1],[l2,r2],...,[ln,rn].现在要从中选出 m 个区间,使得这 m个区间共同包含至少一个位置.换句话说,就 ...
- 题解【bzoj4653 [NOI2016] 区间】
先按照长度排个序,然后依次添加区间.什么是添加?设这个区间是\([l,r]\),添加就是把\(a_l,a_{l+1},a_{l+2},{...},a_{r}\)都加上\(1\),其中\(a_i\)表示 ...
- BZOJ4653: [Noi2016]区间(线段树 双指针)
题意 题目链接 Sol 按照dls的说法,一般这一类的题有两种思路,一种是枚举一个点\(M\),然后check它能否成为答案.但是对于此题来说好像不好搞 另一种思路是枚举最小的区间长度是多少,这样我们 ...
- BZOJ4653(区间离散化+线段树+决策单调尺取)
写得很好的题解 一眼过去很像是:排序,然后从前向后扫,有这个区间时插到树里,过去以后再删除.然后事实也是这样做的…… 具体起来: 1.如果考虑暴力的话,一种想法是枚举左端和右端要选取的区间(如果我们按 ...
随机推荐
- C++之异常捕获和处理
一.简介 在C++语言中,异常处理包括:throw表达式,try语句块,一套异常类.其中,异常类用于在throw表达式和相关的catch子句之间传递异常的具体信息.exception头文件定义了最 ...
- 需求分析&原型设计
需求分析&原型设计 需求分析 访问软件项目真实用户 首先本项目的用户是这个需要做简单四则运算的用户(我们团队通过对家里有三四年级小学生(需要做简单四则运算)的简单采访):反映了几个主要的问题: ...
- io多路复用(三)
#!/usr/bin/env python # -*- coding:utf-8 -*- import socket sk1 = socket.socket() sk1.bind(('127.0.0. ...
- 利用yield 实现Xrange功能
def xrange(n): start = 0 while True: if start>n: return yield start start+=1 obj = xrange(5) n1 = ...
- bzoj千题计划252:bzoj1095: [ZJOI2007]Hide 捉迷藏
http://www.lydsy.com/JudgeOnline/problem.php?id=1095 点分树+堆 请去看 http://www.cnblogs.com/TheRoadToTheGo ...
- 云计算(2)it 是什么
2015年,全世界在it上面的花费达到3亿8千亿美金之多. 云数据中心:核心基础架构,云计算的物理载体,提供数据处理.存储和高性能计算支撑,包括服务器.存储.冷却.机房空间和能耗管理等. 超大规模的云 ...
- AFNetWorking常用方法
NSURLConnection,主要对NSURLConnection进行了进一步的封装,包含以下核心的类: AFURLConnectionOperation AFHTTPRequestOperatio ...
- Maven 私服的简单使用
所有的 Java 开发者应该是没有没用过 Maven 的吧.Maven 作为 Java 项目管理工具,它不仅可以用作包管理,还有许多的插件,可以支持整个项目的开发.打包.测试.部署等一系列行为.而包管 ...
- 爬取IP
import urllib.request import re def url_open(url): req = urllib.request.Request(url,headers={'User-A ...
- equals方法的编写建议
1.显示参数命名为 otherObject ,稍后需要将其转换成另一个叫做 other 的变量. 2.检测 this 与 otherObject 是否引用同一个对象: //这条语句只是一个优化.计算这 ...