题目分析:

首先思考一个二分答案的做法。我们可以注意到答案具有单调性,所以可以二分答案。

假设当前二分的答案是$ k $。那么按照大小顺序插入每个区间,同时在末端删除会对答案产生影响的区间。这里不妨用线段树维护。这个做法在外国好像叫做two pointers。

如果某个时刻,线段树中有点大于等于$ m $,说明这个答案是合理的,可以向上二分。若全程没有点大于$ m $说明这个答案不合理,向下二分。

时间复杂度是$ O(nlognlogN) $的,会超时。

从这个方法入手,考虑如何优化。实际上,二分是不必要的。同样我们可以采用two pointers。如果某个时刻线段树中有点等于$ m $。我们完全可以从后端删除点。这是为什么呢?

理由是从后端删除掉的点与其它点产生的共鸣(姑且这么叫吧)肯定比当前的答案要大,若以删除对更好的答案是没有影响的。这样我们可以删除直到线段树中没有点等于$ m $。同时记录答案。

时间复杂度是$ O(nlogn) $的,可以通过所有数据。

代码:

 #include<bits/stdc++.h>
using namespace std; const int maxn = ; int n,m,Num; int mp[maxn<<]; struct Dir{
int l,r,len;
}d[maxn]; class SegmentTree{
private:
int lazy[maxn<<],maxx[maxn<<];
void push_down(int now){
maxx[now<<] += lazy[now]; lazy[now<<] += lazy[now];
maxx[now<<|] += lazy[now]; lazy[now<<|] += lazy[now];
lazy[now] = ;
}
void push_up(int now){maxx[now] = max(maxx[now<<],maxx[now<<|]);}
public:
void add(int now,int l,int r,int tl,int tr,int val){
if(lazy[now] && tl != tr) push_down(now);
if(tl >= l && tr <= r){
lazy[now] +=val; maxx[now]+=val;
return;
}
if(tl > r || tr < l) return;
int mid = (tl+tr)/;
add(now<<,l,r,tl,mid,val);
add(now<<|,l,r,mid+,tr,val);
push_up(now);
}
int Query(){return maxx[];}
}T; int cmp(Dir a,Dir b){
if(a.len<b.len) return true;
else return false;
} void read(){
scanf("%d%d",&n,&m);
for(int i=;i<=n;i++){
scanf("%d%d",&d[i].l,&d[i].r); d[i].len = d[i].r-d[i].l;
mp[++Num] = d[i].l; mp[++Num] = d[i].r;
}
sort(d+,d+n+,cmp);
sort(mp+,mp+Num+);
Num = unique(mp+,mp+Num+)-mp-;
for(int i=;i<=n;i++){
d[i].l = lower_bound(mp+,mp+Num+,d[i].l)-mp;
d[i].r = lower_bound(mp+,mp+Num+,d[i].r)-mp;
}
} void work(){
int lastans = 2e9;
for(int i=,j=;i<=n;i++){ // two pointers
T.add(,d[i].l,d[i].r,,Num,);
if(T.Query() == m){
while(j <= i){
T.add(,d[j].l,d[j].r,,Num,-);
if(T.Query() != m){
lastans = min(lastans,d[i].len-d[j].len);
j++;
break;
}
j++;
}
}
while(j <= i && d[i].len - d[j].len > lastans){
T.add(,d[j].l,d[j].r,,Num,-);
j++;
}
}
if(lastans == 2e9) puts("-1");
else printf("%d",lastans);
} int main(){
read();
work();
return ;
}

BZOJ4653 [NOI2016] 区间 【线段树】的更多相关文章

  1. BZOJ4653 [NOI2016]区间 [线段树,离散化]

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

  2. BZOJ4653: [Noi2016]区间(线段树 双指针)

    题意 题目链接 Sol 按照dls的说法,一般这一类的题有两种思路,一种是枚举一个点\(M\),然后check它能否成为答案.但是对于此题来说好像不好搞 另一种思路是枚举最小的区间长度是多少,这样我们 ...

  3. BZOJ4653:[NOI2016]区间(线段树)

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

  4. 【BZOJ-4653】区间 线段树 + 排序 + 离散化

    4653: [Noi2016]区间 Time Limit: 60 Sec  Memory Limit: 256 MBSubmit: 107  Solved: 70[Submit][Status][Di ...

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

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

  6. [NOI2016]区间 线段树

    [NOI2016]区间 LG传送门 考虑到这题的代价是最长边减最短边,可以先把边按长度排个序,双指针维护一个尺取的过程,如果存在包含某个点的区间数\(\ge m\),就更新答案并把左指针右移,这样做的 ...

  7. Luogu P1712 [NOI2016]区间(线段树)

    P1712 [NOI2016]区间 题意 题目描述 在数轴上有 \(N\) 个闭区间 \([l_1,r_1],[l_2,r_2],...,[l_n,r_n]\) .现在要从中选出 \(M\) 个区间, ...

  8. UOJ222 NOI2016 区间 线段树+FIFO队列

    首先将区间按长度排序后离散化端点(这里的“长度”指的是离散化之前区间的实际长度) 然后模拟一个队列,区间按排好的顺序依次进入,直到某个点被覆盖了M次.之后依次出队,直到所有点都被覆盖小于M次 修改和询 ...

  9. 洛谷$P1712\ [NOI2016]$区间 线段树

    正解:线段树 解题报告: 传送门$QwQ$ $umm$很久以前做的了来补个题解$QwQ$ 考虑给每个区间按权值($r-l$从大往小排序,依次加入,然后考虑如果有一个位置被覆盖次数等于$m$了就可以把权 ...

  10. hdu 1540 Tunnel Warfare (区间线段树(模板))

    http://acm.hdu.edu.cn/showproblem.php?pid=1540 Tunnel Warfare Time Limit: 4000/2000 MS (Java/Others) ...

随机推荐

  1. Redux 入门教程(三):React-Redux 的用法

    为了方便使用,Redux 的作者封装了一个 React 专用的库 React-Redux,本文主要介绍它. 这个库是可以选用的.实际项目中,你应该权衡一下,是直接使用 Redux,还是使用 React ...

  2. 最长递增子序列(lis)最长公共子序列(lcs) 最长公共上升子序列(lics)

    lis: 复杂度nlgn #include<iostream> #include<cstdio> using namespace std; ],lis[],res=; int ...

  3. c++入门之 深入cin

    cin 表示输入流,但是究其本质,又能认识到什么呢?先上代码: #include "iostream" };//c++11中使用{}进行重新命名 int main() { usin ...

  4. echarts使用笔记四:双Y轴

    1.双Y轴显示数量和占比 app.title = '坐标轴刻度与标签对齐'; option = { title : { //标题 x : 'center', y : 5, text : '数量和占比图 ...

  5. mysql 查看版本

    查看mysql版本的四种方法 - 风生水起 - 博客园 http://www.cnblogs.com/end/archive/2011/10/18/2216461.html 查看mysql数据库版本方 ...

  6. Migrate MySQL database using dump and restore

    kaorimatz/mysqldump-loader: Load a MySQL dump file using LOAD DATA INFILEhttps://github.com/kaorimat ...

  7. 1 Expression of Possiblity

    Expression of possibility Probably     Perhaps There's a change(that) It's very likly(that) It's pos ...

  8. 缓存session,cookie,sessionStorage,localStorage的区别

    https://www.cnblogs.com/cencenyue/p/7604651.html(copy) 浅谈session,cookie,sessionStorage,localStorage的 ...

  9. YAML配置:mapping values are not allowed here

    在配置Eureka服务器配置文件的时候,出现了mapping values not allowed here的错误,原因是的冒号 ”:“后面没有空格. 原因分析:yml文件中,键值对是以": ...

  10. 简单比较init-method,afterPropertiesSet和BeanPostProcessor

    一.简单介绍 1.init-method方法,初始化bean的时候执行,可以针对某个具体的bean进行配置.init-method需要在applicationContext.xml配置文档中bean的 ...