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\)个俄罗斯套娃,每个套娃都有一个\( ...
随机推荐
- [论文总结] 农业工程领域中App和Web相关应用论文笔记
文章目录 1. Tomato leaf segmentation algorithms for mobile phone applications using deep learning 2. Int ...
- Mariadb对数据库和表的操作
登录mariadb: 路径切换到bin下 mysql -u root -p 然后会提示输密码 新建数据库: create database demo; 其中demo为数据库名字 新建表 create ...
- Spark详解(08) - Spark(3.0)内核解析和源码欣赏
Spark详解(08) - Spark(3.0)内核解析和源码欣赏 源码全流程 Spark提交流程(YarnCluster) Spark通讯架构 Spark任务划分 Task任务调度 Shuffle原 ...
- Windows 平台计算 CPU 总利用率
利用 GetSystemTimes 可以获得 Windows 系统的 Idle Time. Kernel Time 和 User Time.Idle Time 是系统空闲的时间,也就是系统没有利用的时 ...
- Js/Jq 截图并上传
今天想做一个 Js + Jq 截取网页图并上传到后端,经过一番折腾最终达到了效果. 1·首先需要用到一个非常强大的外部依赖库 html2canvas html2canvas 官网:html2canva ...
- [cocos2d-x]关于CC_CALLBACK
CC_CALLBACK的代码 // new callbacks based on C++11 #define CC_CALLBACK_0(__selector__,__target__, ...) s ...
- 基于Udp通讯的Java局域网群聊小程序
/**基于Udp通讯的Java局域网群聊小程序 */package com.UdpDemo; import java.net.*; import java.awt.*; import java.awt ...
- Miller-Rabin 与 Pollard-Rho 算法学习笔记
前言 Miller-Rabin 算法用于判断一个数 \(p\) 是否是质数,若选定 \(w\) 个数进行判断,那么正确率约是 \(1-\frac{1}{4^w}\) ,时间复杂度为 \(O(\log ...
- 【AI编译器原理】系列来啦!我们要从入门到放弃!
随着深度学习的应用场景的不断泛化,深度学习计算任务也需要部署在不同的计算设备和硬件架构上:同时,实际部署或训练场景对性能往往也有着更为激进的要求,例如针对硬件特点定制计算代码. 这些需求在通用的AI框 ...
- 数据库实践丨使用MTK迁移Mysql源库后主键自增列导致数据无法插入问题
摘要:用户使用Mogdb 2.0.1版本进行业务上线测试,发现在插入数据时,应用日志中提示primary key冲突,用户自查业务SQL没有问题,接到通知后,招手处理故障. 本文分享自华为云社区< ...