题目链接

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. 【数据库】 SQL 常用语句之系统语法

    [数据库] SQL 常用语句之系统语法 1. 获取取数据库服务器上所有数据库的名字 SELECT name FROM master.dbo.sysdatabases 2. 获取取数据库服务器上所有非系 ...

  2. springmvc基础篇—通过注解的方式去配置项目

    学习了通过xml方式去配置项目后,当然要掌握更简单更灵活的注解方式哟,这是官方推荐使用的方式. 一.修改配置文件,建议大家直接使用我的配置文件 <?xml version="1.0&q ...

  3. SVN 使用时的小错误

    在使用SVN的时候总是出现一些小问题,今天又出现了一个,诶,分享一下吧!  Error:(个人文件夹名http://www.qdjhu.com/anli_xq/f_wancheng.php)  is ...

  4. 标志寄存器PSW和汇编条件转移指令解释

    标志寄存器PSW 标志寄存器PSW(程序状态字寄存器PSW)   标志寄存器PSW是一个16为的寄存器.它反映了CPU运算的状态特征并且存放某些控制标志.8086使用了16位中的9位,包括6个状态标志 ...

  5. Python 3基础教程26-多行打印

    本文来介绍多行打印.多行打印一般出现在欢迎界面,例如你玩过的游戏,第一个界面,很多文字显示. 我们随便打印几行,来模拟下这种多行打印情况. # 多行打印 print(''' 第一行内容 第二行内容 第 ...

  6. 【java并发编程实战】第八章:线程池的使用

    1.线程饥饿锁 定义:在线程池中,如果任务的执行依赖其他任务,那么可能会产生线程饥饿锁.尤其是单线程线程池. 示例: public class ThreadDeadStarveTest { publi ...

  7. 寻找完全数(C++)

    [问题描述] 输入一个大于 1 的正整数 n,请你将大于 1 和小于或等于 n 的所有完全数输出.所谓完全数就是因子(不算其本身)之和等于它本身的数.例如 1+2+4+7+14=28,所以 28 是完 ...

  8. 条件随机场CRF

    条件随机场(CRF)是给定一组输入随机变量X的条件下另一组输出随机变量Y的条件概率分布模型,其特点是假设输出随机变量构成马尔科夫随机场.实际上是定义在时序数据上的对数线性模型.条件随机场属于判别模型. ...

  9. tensorflow学习笔记(2)-反向传播

    tensorflow学习笔记(2)-反向传播 反向传播是为了训练模型参数,在所有参数上使用梯度下降,让NN模型在的损失函数最小 损失函数:学过机器学习logistic回归都知道损失函数-就是预测值和真 ...

  10. picker组件,mode=date,苹果机年份从1开始

    由于在IOS上复制图片不方便, 所以用了张别的网站的图 这是在没有设置value和start的情况下出现的,安卓机上显示是好的.尝试完网上相关说法, 发现都不中! 通过各种挣扎啊!~ 心里苦啊~ 复制 ...