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\)个俄罗斯套娃,每个套娃都有一个\( ...
随机推荐
- Django框架:13、csrf跨站请求伪造、auth认证模块及相关用法
Django框架 目录 Django框架 一.csrf跨站请求伪造 1.简介 2.csrf校验策略 form表单csrf策略 ajax请求csrf策略 3.csrf相关装饰器 FBV添加装饰器方式 C ...
- python之路55 cookie与session 操作 把模块变成字符串进行导入
django中间件三个了解的方法 1.process_view 路由匹配成功之后执行视图函数/类之前自动触发(顺序同process_request) 2.process_exception 视图函数/ ...
- 如何用 30s 给面试官讲清楚什么是 Token
引言 前文介绍了 Session-Cookie 的认证过程,简单回顾下基本步骤: 客户端(浏览器)向服务器发送用户名和密码 服务器验证通过后,创建 Session 对象,在 Session 中保存该用 ...
- [剑指Offer]3.数组中重复的数字
题目 找出数组中重复的数字. 在一个长度为n的数组中的所有数字都在0~n-1的范围内.数组中某些数字是重复的,但是不知道有几个数字重复了,也不知道每个数字重复了几次.请找出数组中任意一个重复的数组.例 ...
- P3845 [TJOI2007]球赛
简要题意 \(T\) 组数据,每一组数据给出 \(n\) 个数对 \((a,b)\).你需要将其分为几组,使得组单调不降.求最小组数. 思路 模拟赛考的题. 先来介绍 Dilworth 定理: 对于任 ...
- Openmp Runtime 库函数汇总(下)——深入剖析锁🔒原理与实现
Openmp Runtime 库函数汇总(下)--深入剖析锁原理与实现 前言 在本篇文章当中主要给大家介绍一下 OpenMP 当中经常使用到的锁并且仔细分析它其中的内部原理!在 OpenMP 当中主要 ...
- Java入门与进阶 P-2.1+P-2.2
比较运算符 关系运算符(relational operators)也可以称为"比较运算符",用于用来比较判断两个变量或常量的大小.关系运算符是二元运算符,运算结果是 boolean ...
- bbs大作业
1.项目开发基本流程 1.需求分析 2.架构设计 3.分组开发 4.提交测试 5.交付上线 2.项目流程 仿造博客园项目(核心:文章的增删改查) 1.表分析: 1.1用户表 1.2个人站点表 1.3文 ...
- MySQL-SQL语法、字段类型
1.字符编码与配置文件 1.\s:查看当前MySQL相关信息:当前用户.版本.编码.端口号. """ Server characterset.Db characterse ...
- 艰难的 debug 经历,vscode 无法获取远程环境 ssh 报错,windows 11 ssh
背景介绍 要做系统结构实验,学校和华为云合作使用华为云的 aarch64 裸机,需要使用 ssh 远程开发,笔者为了追求良好的开发体验,决定使用 vscode 开发,实验环境配置过程中遇到了两个问题, ...