题目链接

emmm看起来好像无从下手,

\(l_i,r_i\)这么大,肯定是要离散化的。

然后我们是选\(m\)个区间,我们先对这些区间按长度排个序也不影响。

排序后,设我们取的\(m\)个区间的编号是\(b_1,b_2,...,b_m\),

若\(b_m\)确定,我们肯定是要尽量使\(b_1,b_2,...,b_{m-1}\)尽量接近\(b_m\)的,这样可使代价最小。

所以,就可以尺取了。

定义两个指针\(l,r\),首先\(r\)指针不停右移覆盖一遍扫到的区间直到满足条件有一个点被连续覆盖\(m\)次,怎么判断?显然维护一棵最大值线段树就好了。

当满足条件,就让\(l\)指针右移直到不满足条件,更新答案。

#include <cstdio>
#include <algorithm>
using std::sort;
#define INF 2147483647
const int MAXN = 650010;
int n, m, q;
char ch;
inline int max(int a, int b){
return a > b ? a : b;
}
inline int min(int a, int b){
return a > b ? b : a;
}
inline int read(){
q = 0; ch = getchar();
while(ch < '0' || ch > '9') ch = getchar();
while(ch >= '0' && ch <= '9') { q = q * 10 + ch - '0'; ch = getchar(); }
return q;
}
struct Seg{
int l, r, len;
bool operator < (const Seg A) const{
return len < A.len;
}
}s[MAXN];
struct LSH{
int id, pos, val;
bool operator < (const LSH A) const{
return val < A.val;
}
}p[MAXN << 1];
int cnt, num;
namespace SegTree{
#define left (now << 1)
#define right (now << 1 | 1)
int Max[MAXN << 2 << 1], lazy[MAXN << 2 << 1];
inline void pushup(int now){
Max[now] = max(Max[left], Max[right]);
}
inline void pushdown(int now){
if(lazy[now]){
Max[left] += lazy[now];
Max[right] += lazy[now];
lazy[left] += lazy[now];
lazy[right] += lazy[now];
lazy[now] = 0;
}
}
void update(int now, int l, int r, int wl, int wr, int p){
if(l >= wl && r <= wr){ Max[now] += p; lazy[now] += p; return; }
pushdown(now);
int mid = (l + r) >> 1;
if(wl <= mid) update(left, l, mid, wl, min(mid, wr), p);
if(wr > mid) update(right, mid + 1, r, max(mid + 1, wl), wr, p);
pushup(now);
}
int query(int now, int l, int r, int wl, int wr){
if(l >= wl && r <= wr) return Max[now];
int ans = 0;
pushdown(now);
int mid = (l + r) >> 1;
if(wl <= mid) ans = max(ans, query(left, l, mid, wl, min(mid, wr)));
if(wr > mid) ans = max(ans, query(right, mid + 1, r, max(mid + 1, wl), wr));
return ans;
}
}using namespace SegTree;
int ans = INF;
int main(){
n = read(); m = read();
for(int i = 1; i <= n; ++i){
s[i].l = read(); s[i].r = read();
s[i].len = s[i].r - s[i].l;
p[++cnt].val = s[i].l; p[cnt].id = i; p[cnt].pos = 1;
p[++cnt].val = s[i].r; p[cnt].id = i; p[cnt].pos = 2;
} p[0].val = -1;
sort(p + 1, p + cnt + 1);
for(int i = 1; i <= cnt; ++i)
if(p[i].pos == 1)
if(p[i].val != p[i - 1].val)
s[p[i].id].l = ++num;
else s[p[i].id].l = num;
else
if(p[i].val != p[i - 1].val)
s[p[i].id].r = ++num;
else s[p[i].id].r = num;
sort(s + 1, s + n + 1);
int l = 1, r = 0;
while(r < n){
while(r < n && Max[1] < m){
++r;
update(1, 1, num, s[r].l, s[r].r, 1);
}
if(Max[1] < m) break;
int tmp;
while(Max[1] >= m) tmp = s[l].len, update(1, 1, num, s[l].l, s[l].r, -1), ++l;
ans = min(ans, s[r].len - tmp);
}
printf("%d\n", ans == INF ? -1 : ans);
return 0;
}

【洛谷 P1712】 [NOI2016]区间 (线段树+尺取)的更多相关文章

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

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

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

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

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

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

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

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

  5. [洛谷P1712] NOI2016 区间

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

  6. 洛谷P3372/poj3468(线段树lazy_tag)(询问区间和,支持区间修改)

    洛谷P3372 //线段树 询问区间和,支持区间修改 #include <cstdio> using namespace std; struct treetype { int l,r; l ...

  7. [NOI2016]区间 线段树

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

  8. 【BZOJ】1012: [JSOI2008]最大数maxnumber /【洛谷】1198(线段树)

    Description 现在请求你维护一个数列,要求提供以下两种操作:1. 查询操作.语法:Q L 功能:查询当前数列中末尾L个数中的最大的数,并输出这个数的值.限制:L不超过当前数列的长度.2. 插 ...

  9. 洛谷题解P4314CPU监控--线段树

    题目链接 https://www.luogu.org/problemnew/show/P4314 https://www.lydsy.com/JudgeOnline/problem.php?id=30 ...

随机推荐

  1. java_hdfs之读写文件

    package hdfsTest.answer.hdfs; import java.io.IOException; import java.net.URI; //import java.net.URL ...

  2. Python 3基础教程31-urllib模块

    本文介绍Python里的urllib模块,这个urllib主要处理web服务的,如果需要做接口测试,或者写Python的网络爬虫,这个urllib就是最底层的库.需要用到里面的请求方法等. 1. 先看 ...

  3. hdu 1556 Color the ball (区间更新 求某点值)

    Problem Description N个气球排成一排,从左到右依次编号为1,2,3....N.每次给定2个整数a b(a <= b),lele便为骑上他的“小飞鸽"牌电动车从气球a ...

  4. windowsserver2008 重新启动计算机命令

    在windowsserver2008中,若要重新启动计算机,可以输入以下命令即可立即重启计算机shutdown -r -t 0命令意义:shutdown在英文中意为关掉,在计算机中即为关机参数意义:- ...

  5. 【iOS开发】UIViewController的基本概念与生命周期

    http://www.cnblogs.com/wayne23/p/3868535.html UIViewController是iOS顶层视图的载体及控制器,用户与程序界面的交互都是由UIViewCon ...

  6. Good Time 冲刺 三

    第三天 日期:2018.6.16 一.今日完成任务情况及遇到的问题 王怡镔:继续在学习微信小程序的设计,完善设计发现页面,开始编写发现页面 于鑫宇:配合黄鹤的工作,学习端口相关知 胡雅馨:继续改进优化 ...

  7. PAT 1080 MOOC期终成绩

    https://pintia.cn/problem-sets/994805260223102976/problems/994805261493977088 对于在中国大学MOOC(http://www ...

  8. 入口文件-npm run dev

    如果你是用vue.js官网提供的脚手架工具并沿用默认配置的话,你执行npm run dev的时候会出来页面,是因为你根目录下的package.json文件里script配置了"dev&quo ...

  9. 【UML】活动图介绍

    1.活动图,即Activity Diagram,是UML中用于对系统的动态行为建模的一种常用工具,它描述活动的顺序,展现从一种活动到另一种活动的控制流.其本质上是一种流程图,着重表现从一个活动到另一个 ...

  10. Chrome Extension & Dark Theme

    Chrome Extension & Dark Theme https://chrome.google.com/webstore/detail/eimadpbcbfnmbkopoojfekhn ...