Educational Codeforces Round 112 E、Boring Segments
原题网址
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的更多相关文章
- Educational Codeforces Round 6 F. Xors on Segments 暴力
F. Xors on Segments 题目连接: http://www.codeforces.com/contest/620/problem/F Description You are given ...
- Educational Codeforces Round 41 B、C、D
http://codeforces.com/contest/961 B题 可以将长度为k的连续区间转化成1 求最大和 解析 简单尺取 #include <stdio.h> #include ...
- Educational Codeforces round 78 A、B
链接:https://codeforces.com/contest/1278 A:Shuffle Hashing 题意:对于一个字符串p可以执行一个"hash"操作,首先将p内的元 ...
- 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 ...
- Educational Codeforces Round 64 (Rated for Div. 2)题解
Educational Codeforces Round 64 (Rated for Div. 2)题解 题目链接 A. Inscribed Figures 水题,但是坑了很多人.需要注意以下就是正方 ...
- Educational Codeforces Round 35 (Rated for Div. 2)
Educational Codeforces Round 35 (Rated for Div. 2) https://codeforces.com/contest/911 A 模拟 #include& ...
- Educational Codeforces Round 63 (Rated for Div. 2) 题解
Educational Codeforces Round 63 (Rated for Div. 2)题解 题目链接 A. Reverse a Substring 给出一个字符串,现在可以对这个字符串进 ...
- Educational Codeforces Round 58 (Rated for Div. 2) 题解
Educational Codeforces Round 58 (Rated for Div. 2) 题目总链接:https://codeforces.com/contest/1101 A. Min ...
- Educational Codeforces Round 40千名记
人生第二场codeforces.然而遇上了Education场这种东西 Educational Codeforces Round 40 下午先在家里睡了波觉,起来离开场还有10分钟. 但是突然想起来还 ...
- Educational Codeforces Round 69 (Rated for Div. 2) E. Culture Code
Educational Codeforces Round 69 (Rated for Div. 2) E. Culture Code 题目链接 题意: 给出\(n\)个俄罗斯套娃,每个套娃都有一个\( ...
随机推荐
- 深入理解C++虚函数底层机制和RTTI运行时类型识别
当调用一个虚函数时,被执行的代码必须与调用函数对象的动态类型相一致:指向对象的指针或引用的类型是不重要的,编译器是如何高效地提供这种行为呢?大多数编译器是使用virtual table和virtual ...
- dispatch_source_t定时器
定时器简述 在iOS中,计时器是比较常用的,用于统计累加数据或者倒计时等,计时器大概有那么三种,分别是: NSTimer CADisplayLink dispatch_source_t 比较 1.NS ...
- os 模块 sys模块 json模块
今日内容详细 os模块(重要) os模块主要与代码运行所在的操作系统打交道 import os 1.创建目录 1.创建目录(文件夹) os.mkdir(r'L4') # 只可以创建单级目录 相对路径 ...
- Unity - 自定义Log
嗨,崽崽们大家好.实在是不知道写个啥了,最近总是恍惚,今儿偷个懒吧,给大家推荐一个小黑自己写的小型日志工具,在一些小项目中管够使用了. 那有人会问了,Unity不是自带日志么,为什么还要自己做个小工具 ...
- 【FAQ】申请运动健康服务验证环节常见问题及解答
华为 HMS Core 运动健康服务(HUAWEI Health Kit)提供原子化数据开放.应用在获取用户数据授权后,可通过接口访问运动健康数据,对用户数据进行读写等操作,为用户提供运动健康类数据服 ...
- 12月9日内容总结——静态文件以及配置、form表单属性的作用、request对象、python连接数据库和Django连接数据库、ORM的基础知识介绍
目录 一.静态文件 1.静态文件概念 2.资源访问 3.静态文件资源访问 二.静态文件相关配置 1.接口前缀 2.接口前缀动态匹配 三.form表单 action属性 method属性 四.reque ...
- Linux文件常用操作命令
Linux文件常用操作命令 一.Linux文件和目录简单操作 1.1 查看文件 ls 查看当前目录下的文件 如: -a 显示所有文件及目录 (ls内定将文件名或目录名称开头为"." ...
- Kubernetes环境cert-manager部署与应用
本作品由Galen Suen采用知识共享署名-非商业性使用-禁止演绎 4.0 国际许可协议进行许可.由原作者转载自个人站点. 概述 本文用于整理基于Kubernetes环境的cert-manager部 ...
- 2211-12 Hello Flask!
本篇记录来自Flask 入门教程 第 2 章:Hello, Flask! 第 2 章:Hello, Flask! 追溯到最初,Flask 诞生于 Armin Ronacher 在 2010 年愚人节开 ...
- Vue视频 | 【Vue2 + Vue3 前端教程】完整版
目前大部分公司还是以vue.react技术为主的,而Vue中还是以Vue2为主流,但不可否认Vue3是未来所必须的且已有这个趋向了 今天给大家介绍一个Vue的教程 里面既有现在主流的Vue2 同时也存 ...