原题网址

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)。

我的代码

#include <bits/stdc++.h>
using namespace std;
using ll = long long;
constexpr int maxn = 300000;
constexpr int maxm = 2000000;
constexpr int inf = 0x7fffffff; struct seg {
int l, r, w;
}; bool operator<(const seg& a, const seg& b) { return a.w < b.w; } int n, m;
int tree[maxm * 4 + 2];
int lazy[maxm * 4 + 2];
seg segs[maxn + 4]; inline int lc(int i) { return i << 1; }
inline int rc(int i) { return (i << 1) + 1; } inline void pushdown(int i) {
lazy[lc(i)] += lazy[i], lazy[rc(i)] += lazy[i];
tree[lc(i)] += lazy[i], tree[rc(i)] += lazy[i];
lazy[i] = 0;
} int query(int s, int e, int l, int r, int i) {
if (s <= l && r <= e) return tree[i];
pushdown(i);
auto m = (l + r) >> 1;
int sum = inf;
if (s <= m) sum = min(query(s, e, l, m + 1, lc(i)), sum);
if (e >= m + 1) sum = min(query(s, e, m + 1, r, rc(i)), sum);
return sum;
} void update(int s, int e, int l, int r, int i, int val) {
if (s <= l && r <= e) {
lazy[i] += val, tree[i] += val;
return;
}
pushdown(i);
auto m = (l + r) >> 1;
if (s <= m) update(s, e, l, m, lc(i), val);
if (e >= m + 1) update(s, e, m + 1, r, rc(i), val);
tree[i] = min(tree[lc(i)], tree[rc(i)]);
} int main() {
scanf("%d%d", &n, &m); for (int i = 1; i <= n; ++i) {
scanf("%d%d%d", &segs[i].l, &segs[i].r, &segs[i].w);
}
sort(segs + 1, segs + n + 1); int p2 = 1;
int ans = inf;
for (int p1 = 1; p1 <= n; ++p1) {
while (p2 < n + 1 && query(1, m - 1, 1, m - 1, 1) == 0) {
update(segs[p2].l, segs[p2].r - 1, 1, m - 1, 1, 1);
++p2;
}
if (query(1, m - 1, 1, m - 1, 1) == 0) break;
ans = min(ans, segs[p2 - 1].w - segs[p1].w);
update(segs[p1].l, segs[p1].r - 1, 1, m - 1, 1, -1);
}
printf("%d\n", ans);
return 0;
}

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. [论文总结] 农业工程领域中App和Web相关应用论文笔记

    文章目录 1. Tomato leaf segmentation algorithms for mobile phone applications using deep learning 2. Int ...

  2. Mariadb对数据库和表的操作

    登录mariadb: 路径切换到bin下 mysql -u root -p 然后会提示输密码 新建数据库: create database demo; 其中demo为数据库名字 新建表 create ...

  3. Spark详解(08) - Spark(3.0)内核解析和源码欣赏

    Spark详解(08) - Spark(3.0)内核解析和源码欣赏 源码全流程 Spark提交流程(YarnCluster) Spark通讯架构 Spark任务划分 Task任务调度 Shuffle原 ...

  4. Windows 平台计算 CPU 总利用率

    利用 GetSystemTimes 可以获得 Windows 系统的 Idle Time. Kernel Time 和 User Time.Idle Time 是系统空闲的时间,也就是系统没有利用的时 ...

  5. Js/Jq 截图并上传

    今天想做一个 Js + Jq 截取网页图并上传到后端,经过一番折腾最终达到了效果. 1·首先需要用到一个非常强大的外部依赖库 html2canvas html2canvas 官网:html2canva ...

  6. [cocos2d-x]关于CC_CALLBACK

    CC_CALLBACK的代码 // new callbacks based on C++11 #define CC_CALLBACK_0(__selector__,__target__, ...) s ...

  7. 基于Udp通讯的Java局域网群聊小程序

    /**基于Udp通讯的Java局域网群聊小程序 */package com.UdpDemo; import java.net.*; import java.awt.*; import java.awt ...

  8. Miller-Rabin 与 Pollard-Rho 算法学习笔记

    前言 Miller-Rabin 算法用于判断一个数 \(p\) 是否是质数,若选定 \(w\) 个数进行判断,那么正确率约是 \(1-\frac{1}{4^w}\) ,时间复杂度为 \(O(\log ...

  9. 【AI编译器原理】系列来啦!我们要从入门到放弃!

    随着深度学习的应用场景的不断泛化,深度学习计算任务也需要部署在不同的计算设备和硬件架构上:同时,实际部署或训练场景对性能往往也有着更为激进的要求,例如针对硬件特点定制计算代码. 这些需求在通用的AI框 ...

  10. 数据库实践丨使用MTK迁移Mysql源库后主键自增列导致数据无法插入问题

    摘要:用户使用Mogdb 2.0.1版本进行业务上线测试,发现在插入数据时,应用日志中提示primary key冲突,用户自查业务SQL没有问题,接到通知后,招手处理故障. 本文分享自华为云社区< ...