原题网址

https://codeforces.com/contest/1555/problem/E

题目大意

有n个区间。每个区间是[1,m]的子区间。从a可以一步走到b的充要条件是存在区间同时覆盖[a,b]。若n个区间中取出一些区间后,可以只通过被取出的区间从1走到m,则称这些被取出的区间组成的集合A是好的。每个区间有价值w,求一个好的集合A的所有元素中,最大价值与最小价值的差的最小值。

数据结构

线段树,支持以下两种操作:

  • 插入或删除区间
  • 查询当前区间集合是否为好的

若一个区间集是好的,则1.5,2.5,...,m-0.5都至少被一个区间覆盖,区间[a,b]可以覆盖a+0.5,...,b-0.5。所以我们可以将每个区间的右端点减一后再操作,线段树第a个元素表示a+0.5被多少个区间覆盖。这样只要查询线段树中[1,m-1]最小值是否为0,不为0即好的。

由于m较大,必须使用懒修改方法,每个节点增加lazy值(区别于真正的val值)。需要注意:

  • 访问某节点时,先进行push操作(将本节点lazy值转给val值,如果还有孩子,则lazy值传递给孩子,清空本节点lazy值),不管被查区间是多少(若l>r也要push,因为只要能递归到,就表示该点实际上表示了一个区间,需要把lazy值转给val值)。
  • 修改时,如果某个节点表示的区间全都要修改,只修改该节点lazy值,不递归。改完后必须进行push操作,把lazy值转成val并传递给孩子。
  • 递归返回时,将两个孩子的val组合成本节点的val。

解题思路

本题为最优化问题。显然尽可能选价值差较小的区间。

先将所有区间按价值排序。

用双指针维护一个范围,左指针为给定价值最小值时,右指针为最小的价值最大值。

枚举所有最小值,根据最小值指针和线段树查询结果移动最大值指针并更新最后答案(用最大值-最小值更新ans)。

我的代码

  1. #include <bits/stdc++.h>
  2. using namespace std;
  3. using ll = long long;
  4. constexpr int maxn = 300000;
  5. constexpr int maxm = 2000000;
  6. constexpr int inf = 0x7fffffff;
  7. struct seg {
  8. int l, r, w;
  9. };
  10. bool operator<(const seg& a, const seg& b) { return a.w < b.w; }
  11. int n, m;
  12. int tree[maxm * 4 + 2];
  13. int lazy[maxm * 4 + 2];
  14. seg segs[maxn + 4];
  15. inline int lc(int i) { return i << 1; }
  16. inline int rc(int i) { return (i << 1) + 1; }
  17. inline void pushdown(int i) {
  18. lazy[lc(i)] += lazy[i], lazy[rc(i)] += lazy[i];
  19. tree[lc(i)] += lazy[i], tree[rc(i)] += lazy[i];
  20. lazy[i] = 0;
  21. }
  22. int query(int s, int e, int l, int r, int i) {
  23. if (s <= l && r <= e) return tree[i];
  24. pushdown(i);
  25. auto m = (l + r) >> 1;
  26. int sum = inf;
  27. if (s <= m) sum = min(query(s, e, l, m + 1, lc(i)), sum);
  28. if (e >= m + 1) sum = min(query(s, e, m + 1, r, rc(i)), sum);
  29. return sum;
  30. }
  31. void update(int s, int e, int l, int r, int i, int val) {
  32. if (s <= l && r <= e) {
  33. lazy[i] += val, tree[i] += val;
  34. return;
  35. }
  36. pushdown(i);
  37. auto m = (l + r) >> 1;
  38. if (s <= m) update(s, e, l, m, lc(i), val);
  39. if (e >= m + 1) update(s, e, m + 1, r, rc(i), val);
  40. tree[i] = min(tree[lc(i)], tree[rc(i)]);
  41. }
  42. int main() {
  43. scanf("%d%d", &n, &m);
  44. for (int i = 1; i <= n; ++i) {
  45. scanf("%d%d%d", &segs[i].l, &segs[i].r, &segs[i].w);
  46. }
  47. sort(segs + 1, segs + n + 1);
  48. int p2 = 1;
  49. int ans = inf;
  50. for (int p1 = 1; p1 <= n; ++p1) {
  51. while (p2 < n + 1 && query(1, m - 1, 1, m - 1, 1) == 0) {
  52. update(segs[p2].l, segs[p2].r - 1, 1, m - 1, 1, 1);
  53. ++p2;
  54. }
  55. if (query(1, m - 1, 1, m - 1, 1) == 0) break;
  56. ans = min(ans, segs[p2 - 1].w - segs[p1].w);
  57. update(segs[p1].l, segs[p1].r - 1, 1, m - 1, 1, -1);
  58. }
  59. printf("%d\n", ans);
  60. return 0;
  61. }

Educational Codeforces Round 112 E、Boring Segments的更多相关文章

  1. Educational Codeforces Round 6 F. Xors on Segments 暴力

    F. Xors on Segments 题目连接: http://www.codeforces.com/contest/620/problem/F Description You are given ...

  2. Educational Codeforces Round 41 B、C、D

    http://codeforces.com/contest/961 B题 可以将长度为k的连续区间转化成1 求最大和 解析 简单尺取 #include <stdio.h> #include ...

  3. Educational Codeforces round 78 A、B

    链接:https://codeforces.com/contest/1278 A:Shuffle Hashing 题意:对于一个字符串p可以执行一个"hash"操作,首先将p内的元 ...

  4. Educational Codeforces Round 13 A、B、C、D

    A. Johny Likes Numbers time limit per test 0.5 seconds memory limit per test 256 megabytes input sta ...

  5. Educational Codeforces Round 64 (Rated for Div. 2)题解

    Educational Codeforces Round 64 (Rated for Div. 2)题解 题目链接 A. Inscribed Figures 水题,但是坑了很多人.需要注意以下就是正方 ...

  6. Educational Codeforces Round 35 (Rated for Div. 2)

    Educational Codeforces Round 35 (Rated for Div. 2) https://codeforces.com/contest/911 A 模拟 #include& ...

  7. Educational Codeforces Round 63 (Rated for Div. 2) 题解

    Educational Codeforces Round 63 (Rated for Div. 2)题解 题目链接 A. Reverse a Substring 给出一个字符串,现在可以对这个字符串进 ...

  8. Educational Codeforces Round 58 (Rated for Div. 2) 题解

    Educational Codeforces Round 58 (Rated for Div. 2)  题目总链接:https://codeforces.com/contest/1101 A. Min ...

  9. Educational Codeforces Round 40千名记

    人生第二场codeforces.然而遇上了Education场这种东西 Educational Codeforces Round 40 下午先在家里睡了波觉,起来离开场还有10分钟. 但是突然想起来还 ...

  10. Educational Codeforces Round 69 (Rated for Div. 2) E. Culture Code

    Educational Codeforces Round 69 (Rated for Div. 2) E. Culture Code 题目链接 题意: 给出\(n\)个俄罗斯套娃,每个套娃都有一个\( ...

随机推荐

  1. day13-功能实现12

    家居网购项目实现012 以下皆为部分代码,详见 https://github.com/liyuelian/furniture_mall.git 29.功能27-Ajax检验注册名 29.1需求分析/图 ...

  2. 使用Logstash工具导入sqlserver数据到elasticSearch及elk分布式日志中心

    首先记下这个笔记,Logstash工具导入sqlserver数据到elasticSearch. 因为logstash使用java写的,我本地开发是win11,所以javade jdk必须要安装.具体安 ...

  3. DVWA靶场实战(十)——XSS(DOM)

    DVWA靶场实战(十) 五.XSS(DOM): 1.漏洞原理: XSS全称为Cross Site Scripting,由于和层叠样式表(Cascading Style Sheets,CSS)重名,所以 ...

  4. 解析url地址hashhref

  5. python命令行参数argparse常用命令

    1.参数个数控制 parser.add_argument('-i', '--integers', nargs='?', const=100, type=int, help='input a numbe ...

  6. 跟着廖雪峰学python 003

    ​ ​编辑 列表和元组 list 是一种有序.可变的数据类型,可添加删除其中的元素. len()函数:可以获取列表元素的个数 classmates = ['Micheal' , 'Bob' , 'Ja ...

  7. sun.security.validator.ValidatorException: PKIXpath building failed: sun.security.provider,javax.net.ssT.SSLHandshakeExceptions.certpath.SunCertPathBuilderException

    报错信息: sun.security.validator.ValidatorException: PKIXpath building failed: sun.security.provider,jav ...

  8. App测试Android的闪退总结

    Android的闪退有三种情况: 第一种:没有任何弹框提示,直接退出 第二种:有弹框提示程序异常 第三种:ANR无响应 三种情况的日志提交和检索方法:  第一种情况:是底层C挂了 **首先:提交客户端 ...

  9. 真正“搞”懂HTTP协议12之缓存代理

    我们在前两篇的内容中分别学习了缓存和代理,大致了解了缓存有哪些头字段,代理是如何服务于服务器和客户端的,那么把两者结合起来,代理缓存,也就是说代理服务器也可以缓存,当客户端请求数据的时候,未必一定要追 ...

  10. window系统增强优化工具

    计算机系统优化的作用很多,它可以清理WINDOWS临时文件夹中的临时文件,释放硬盘空间:可以清理注册表里的垃圾文件,减少系统错误的产生:它还能加快开机速度,阻止一些程序开机自动执行:还可以加快上网和关 ...