题目链接

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. 给apk签名

    一.签名 把apk和签名文件放在jdk bin目录下,然后在jkd bin目录下执行以下代码: jarsigner -verbose -keystore xxx.keystore -signedjar ...

  2. 在Android上,怎样与Kotlin一起使用Retrofit(KAD21)

    作者:Antonio Leiva 时间:Apr 18, 2017 原文链接:https://antonioleiva.com/retrofit-android-kotlin/ 这是又一个例子,关于怎样 ...

  3. CSS实现自适应下保持宽高比

    在项目中,我们可能经常使得自己设计的网页能自适应.特别是网站中的图片,经常要求在网页放大(或缩小)时,宽高同时放大(或缩小),而且不变形(即保持正常的长宽比).为了不变形,常用的方法就是设置width ...

  4. ZooKeeper完全分布式安装与配置

    Apache ZooKeeper是一个为分布式应用所设计开源协调服务,其设计目是为了减轻分布式应用程序所承担的协调任务.可以为用户提供同步.配置管理.分组和命名服务. 1.环境说明 在三台装有cent ...

  5. 九度OJ--Q1164

    import java.util.Scanner; /* * 题目描述: * 任意输入两个9阶以下矩阵,要求判断第二个是否是第一个的旋转矩阵,如果是,输出旋转角度(0.90.180.270),如果不是 ...

  6. DM8168通过GPMC接口与FPGA高速数据通信实现

    硬件:TI达芬奇TMS320DM8168(以下简称DSP).EP4CE6E22C8N(以下简称FPGA) 软件:linux-2.6.37 转载请注明出处- http://www.cnblogs.com ...

  7. Mapper的方式总结

    Mapper的方式总结: <mappers> <!-- 通过package元素将会把指定包下面的所有Mapper接口进行注册 --> <package name=&quo ...

  8. 软工实践Beta冲刺(3/7)

    队名:起床一起肝活队 组长博客:博客链接 作业博客:班级博客本次作业的链接 组员情况 组员1(队长):白晨曦 过去两天完成了哪些任务 描述: 1.界面的修改与完善 展示GitHub当日代码/文档签入记 ...

  9. lincode-58-四数之和

    58-四数之和 给一个包含n个数的整数数组S,在S中找到所有使得和为给定整数target的四元组(a, b, c, d). 注意事项 四元组(a, b, c, d)中,需要满足a <= b &l ...

  10. hash function比较

    http://blog.csdn.net/kingstar158/article/details/8028635 由于工作需要,针对千万级别的数据,使用stl::map着实存在着效率问题,最后使用bo ...