BZOJ_4653_[Noi2016]区间_线段树+离散化+双指针

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

把区间按长度排序。
可以发现我选择一段连续区间的区间一定不会使答案变差。并且合法的两个端点单调。
于是可以用双指针扫一遍,每次确定合法的最短的区间,更新答案。
每次加入/删除一个区间相当于区间加/减,区间求最值操作,这个可以用线段树实现。
区间需要离散化,有用的只有左右端点。
 
代码:
#include <stdio.h>
#include <string.h>
#include <algorithm>
using namespace std;
#define N 500050
#define ls p<<1
#define rs p<<1|1
int n,m,turn[N<<1],maxn;
int t[N<<3],add[N<<3];
struct A {
int l,r,lx,rx;
}q[N];
bool cmp1(const A &x,const A &y) {return x.r-x.l<y.r-y.l;}
int p[N<<1];
inline void pushup(int p) {
t[p]=max(t[ls],t[rs]);
}
inline void pushdown(int p) {
int d;
if(d=add[p]) {
t[ls]+=d; t[rs]+=d;
add[ls]+=d; add[rs]+=d;
add[p]=0;
}
}
void update(int l,int r,int x,int y,int v,int p) {
if(x<=l&&y>=r) {
t[p]+=v; add[p]+=v;
return ;
}
pushdown(p);
int mid=(l+r)>>1;
if(x<=mid) update(l,mid,x,y,v,ls);
if(y>mid) update(mid+1,r,x,y,v,rs);
pushup(p);
}
int query(int l,int r,int x,int y,int p) {
if(x<=l&&y>=r) return t[p];
pushdown(p);
int mid=(l+r)>>1,re=0;
if(x<=mid) re=max(re,query(l,mid,x,y,ls));
if(y<mid) re=max(re,query(mid+1,r,x,y,rs));
pushup(p);
return re;
}
int main() {
scanf("%d%d",&n,&m);
int i,x,y;
for(i=1;i<=n;i++) {
scanf("%d%d",&q[i].l,&q[i].r);
p[i]=q[i].l,p[i+n]=q[i].r;
}
sort(p+1,p+2*n+1);
int j=0;p[0]=5343453;
for(i=1;i<=n;i++) {
q[i].lx=lower_bound(p+1,p+n+n+1,q[i].l)-p;
q[i].rx=lower_bound(p+1,p+n+n+1,q[i].r)-p;
}
maxn=2*n;
sort(q+1,q+n+1,cmp1);
//for(i=1;i<=n;i++) printf("%d %d\n",turn[q[i].l],turn[q[i].r]);
int l=1,r=0,ans=1<<30;
while(r<n) {
while(t[1]<m&&r<n) r++,update(1,maxn,q[r].lx,q[r].rx,1,1);
if(t[1]<m) break;
while(t[1]>=m&&l<n) update(1,maxn,q[l].lx,q[l].rx,-1,1),l++;
ans=min(ans,q[r].r-q[r].l-q[l-1].r+q[l-1].l);
}
printf("%d\n",ans<(1<<30)?ans:-1);
}

BZOJ_4653_[Noi2016]区间_线段树+离散化+双指针的更多相关文章

  1. 【题解】P1712 [NOI2016]区间(贪心+线段树)

    [题解]P1712 [NOI2016]区间(贪心+线段树) 一个observe是,对于一个合法的方案,将其线段长度按照从大到小排序后,他极差的来源是第一个和最后一个.或者说,读入的线段按照长度分类后, ...

  2. 2018.08.17 bzoj4653: [Noi2016]区间(线段树+尺取法)

    传送门 将坐标离散化之后直接用尺取法(双指针)+线段树维护. 其实就是说只要目前所有点的被覆盖次数是大于等于m的就移动左指针删除区间更新答案,否则移动右指针加入区间更新答案. 话说忘记排序以及建树的时 ...

  3. [BZOJ4653][NOI2016]区间 贪心+线段树

    4653: [Noi2016]区间 Time Limit: 60 Sec  Memory Limit: 256 MB Description 在数轴上有 n个闭区间 [l1,r1],[l2,r2],. ...

  4. 【洛谷 P1712】 [NOI2016]区间 (线段树+尺取)

    题目链接 emmm看起来好像无从下手, \(l_i,r_i\)这么大,肯定是要离散化的. 然后我们是选\(m\)个区间,我们先对这些区间按长度排个序也不影响. 排序后,设我们取的\(m\)个区间的编号 ...

  5. NOI2016 区间 【线段树】

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

  6. 洛谷 P1712 [NOI2016]区间(线段树)

    传送门 考虑将所有的区间按长度排序 考虑怎么判断点被多少区间覆盖,这个可以离散化之后用一棵权值线段树来搞 然后维护两个指针$l,r$,当被覆盖次数最多的点的覆盖次数小于$m$时不断右移$r$,在覆盖次 ...

  7. BZOJ4653 [NOI2016] 区间 【线段树】

    题目分析: 首先思考一个二分答案的做法.我们可以注意到答案具有单调性,所以可以二分答案. 假设当前二分的答案是$ k $.那么按照大小顺序插入每个区间,同时在末端删除会对答案产生影响的区间.这里不妨用 ...

  8. dutacm.club_1094_等差区间_(线段树)(RMQ算法)

    1094: 等差区间 Time Limit:5000/3000 MS (Java/Others)   Memory Limit:163840/131072 KB (Java/Others)Total ...

  9. 【BZOJ4653】【NOI2016】区间(线段树)

    [BZOJ4653][NOI2016]区间(线段树) 题面 BZOJ 题解 \(NOI\)良心送分题?? 既然是最大长度减去最小长度 莫名想到那道反复减边求最小生成树 从而求出最小的比值 所以这题的套 ...

随机推荐

  1. objc/runtime.h 查看私有api

    objc/runtime.h 相关 Objecitve-C的重要特性是Runtime(运行时),在Interacting with the Runtime(交互运行)中,运行时函数部分,苹果给出了/u ...

  2. eclipse中英文(等各国语言)版本转换发放

    eclipse界面语言的切换方法 1.该方法只支持安装过中文包的eclipse(其实中文包中几乎包含了全世界所有的语言,只是调用了其中的中文简体而已) 2.在桌面的快捷方式中目标的地址后面加上参数-n ...

  3. js获取Session的值

    纯htm页面必须采用AJAX了, ASP页面:var manager='<%=session("manager")%>', ASPX页面:var manager='&l ...

  4. Java反射之修改常量值

    1. 通过反射修改常量的值 package com.blueStarWei.invoke; import java.lang.reflect.Field; public class ModifyFin ...

  5. jsoup 使用总结3--高级用法之 not

    jsoup 使用总结3--高级用法之 not 大部分时候,我们使用jsoup解析网页的时候,都是直接找到某一类元素,或者按某种selector查询:具体使用方法可以参考jsoup官网文档 例子代码: ...

  6. php数据导出excel

    /** * 导出数据为excel表格 *@param $data 一个二维数组,结构如同从数据库查出来的数组 *@param $title excel的第一行标题,一个数组,如果为空则没有标题 *@p ...

  7. HTML 标签小细节

    简书地址:https://www.jianshu.com/p/03a23aa28a34 今天重新学习了一下HTML中标签的用法,补充并记录一下自己新学到的知识. a中的href href Contai ...

  8. sniffer 简介

    http://www.doc88.com/p-095375416629.html 介绍sniffer的工作原理及简单介绍.

  9. Centos6离线安装MySQL5.5.55-1(附带安装包及Perl依赖包)

    资源包下载https://pan.baidu.com/s/1U3myYp4GSmDUfZocMWI9FA 密码:xdac 资源包所带有的资源截图 1.上传MySQL-client-5.5.55-1.l ...

  10. php 阿里云短信服务及阿里大鱼实现短信验证码的发送

    一:使用阿里云的短信服务 ① 申请短信签名 ②申请短信模板 ③创建Access Key,获取AccessKeyId 与 AccessKeySecret.(为了安全起见,这里建议使用子用户的Access ...