ARC 175 C 题解
我们考虑经典套路,假设前 \(i - 1\) 个数已经被确定。
设 \(f_k(x)\) 表示 \(a_k = x\) 时 \(\sum_{i = k + 1}^n | \ a_i - a_{i - 1} \ |\) 的最小值。
那么,\(a_i = x\) 当且仅当 \(x\) 取最小值且 \(| \ x - a_{i - 1} \ | + f_i(x)\) 为所有可能中的最小值。
我们设集合 \(I_k = \operatorname{argmin}_{x \in [l_k, r_k]} f_k(x)\)。
一个奇妙性质:\(I_k\) 一定是一个区间。
感性理解。容易发现 \(f_k\) 是一个凸函数,所以当取到最小值时,取值定为一个区间。
我们考虑 \(f_k(x)\) 怎么求。
丁真一下。我们可以考虑直接贪心。若 \(a_i = p\),则 \(a_{i + 1}\) 取 \(\operatorname{argmin}_{x \in [l_k, r_k]} | \ x - p \ |\)。然后转移还是比较简单的。
我们设 \(m_k = \min_{x \in [L_k, R_k]}\{f_k(x)\}\):
m_{k+1} + l_k - x & (x < l_k)\\
m_{k+1} & (x\in [l_k, r_k])\\
m_{k+1} + x - r_k & (r_k < x)
\end{cases}
\]
以上贪心可以通过大力分讨得证。但是这一眼正确吧。
那么我们观察 \(f_k(x)\) 的转移式,发现最小值是非常能确定的。于是得到下列结论:
- 如果 \([L_k, R_k] \cap I_{k+1} \neq \emptyset\),则 \(I_k = [L_k, R_k] \cap I_{k+1}\)。
- 如果 \(R_k < l_{k + 1}\),则 \(I_k = R_k\)。
- 如果 \(L_k > r_{k + 1}\),则 \(I_k = L_k\)。
综上,我们求出了 \(I\)。\(f\) 实际上不需要求出。
回到原题。我们要找到 \(x\) 使 \(x\) 取最小值且 \(| \ x - a_{i - 1} \ | + f_i(x)\) 为所有可能中的最小值。
仍然是大力分讨:
\(a_{i - 1} \in I_i\) 时,\(a_i = a_{i - 1}\)。
\(L_i \leq a_{i - 1} < l_i\) 时,\(a_i = a_{i - 1}\)。
\(a_{i - 1} < L_i\) 时,\(a_i = l_i\)。
\(a_{i - 1} > r_i\) 时,\(a_i = r_i\)。
发现上述过程可以简化为 \(a_i\) 取 \([L_i, r_i]\) 中最靠近 \(a_{i - 1}\) 的值。
以下是代码实现。
#include <bits/stdc++.h>
using namespace std;
long long read() {
char c = getchar();
long long x = 0, p = 1;
while ((c < '0' || c > '9') && c != '-') c = getchar();
if (c == '-') p = -1, c = getchar();
while (c >= '0' && c <= '9')
x = (x << 1) + (x << 3) + (c ^ 48), c = getchar();
return x * p;
}
const int N = 5e5 + 7;
int n;
int l[N], r[N], L[N], R[N];
int ans[N];
void solve() {
n = read();
for (int i = 1; i <= n; i ++)
L[i] = read(), R[i] = read();
l[n] = L[n], r[n] = R[n];
for(int i = n - 1; i >= 1; i --) {
if (R[i] < l[i + 1]) {
l[i] = r[i] = R[i];
} else if (L[i] > r[i + 1]) {
l[i] = r[i] = L[i];
} else {
l[i] = max(L[i], l[i + 1]);
r[i] = min(R[i], r[i + 1]);
}
}
ans[1] = l[1];
for(int i = 2; i <= n; i++) {
if (ans[i - 1] >= l[i] && ans[i - 1] <= r[i])
ans[i] = ans[i - 1];
else if (ans[i - 1] >= L[i] && ans[i - 1] < l[i])
ans[i] = ans[i - 1];
else if (ans[i - 1] < L[i])
ans[i] = L[i];
else ans[i] = r[i];
}
for(int i = 1; i <= n; i ++) cout << ans[i] << ' ';
}
signed main() {
int t = 1;
while (t --) solve();
return 0;
}
ARC 175 C 题解的更多相关文章
- ARC 122 简要题解
ARC 122 简要题解 传送门 A - Many Formulae 考虑对于每个数分别算其贡献. 通过枚举该数前面的符号,借助一个非常简单的 \(\mathrm{DP}\)(\(f_{i,0/1}\ ...
- HTML5移动开发学习笔记之Canvas基础
1.第一个Canvas程序 看的是HTML5移动开发即学即用这本书,首先学习Canvas基础,废话不多说,直接看第一个例子. 效果图为: 代码如下: <!DOCTYPE html> < ...
- HTML5系列:HTML5绘图
1. canvas元素基础 canvas元素是HTML5中新增的一个重要元素,专门用来绘制图形. 在页面中使用canvas元素绘制图形需要经过的三个步骤: 步骤一 使用canvas元素创建一个画布区 ...
- 2015年---移动端webapp知识总结
没想到这样又过了5个月了,近期辞职了,所以我有时间来做总结. 这段时间里我学习了很多东西,而且都是我们移动端webapp的同学值得去学习的. 我先告诉大家我这次写的总结,有以下内容: 1.body的背 ...
- 用画布canvas画安卓logo
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- window环境下备份与恢复(实际操作)
C:\Documents and Settings\xuzhengzhu>sqlplus /nolog SQL*Plus: Release 10.2.0.1.0 - Production on ...
- 【题解】Atcoder ARC#96 F-Sweet Alchemy
首先,我们发现每一个节点所选择的次数不好直接算,因为要求一个节点被选择的次数大于等于父亲被选择的次数,且又要小于等于父亲被选择的次数 \(+D\).既然如此,考虑一棵差分的树,规定每一个节点被选择的次 ...
- 【题解】Atcoder ARC#94 F-Normalization
再次膜拜此强题!神级性质之不可能发现系列收藏++:首先,对于长度<=3的情况,我们采取爆搜答案(代码当中是打表).对于长度>=4的情况,则有如下几条玄妙的性质: 首先我们将 a, b, c ...
- [题解] Atcoder Regular Contest ARC 148 A B C E 题解
点我看题 题目质量一言难尽(至少对我来说 所以我不写D的题解了 A - mod M 发现如果把M选成2,就可以把答案压到至多2.所以答案只能是1或2,只要判断答案能不能是1即可.如果答案是1,那么M必 ...
- [题解] Atcoder Regular Contest ARC 147 A B C D E 题解
点我看题 A - Max Mod Min 非常诈骗.一开始以为要观察什么神奇的性质,后来发现直接模拟就行了.可以证明总操作次数是\(O(nlog a_i)\)的.具体就是,每次操作都会有一个数a被b取 ...
随机推荐
- H5完美适配刘海屏和状态栏高度的全机型解决方案攻略
@charset "UTF-8"; .markdown-body { line-height: 1.75; font-weight: 400; font-size: 15px; o ...
- 解决Spring Boot项目后端接口返回数据中文乱码问题
摘要 解决 Spring Boot 项目中,后端返回前端的结果出现中文乱码的问题. 这几天在使用 Spring Boot 学习AOP原理的时候,通过浏览器访问后端接口的时候,响应报文总是出现中文乱 ...
- Leangoo助力医药行业项目降本增效
医药行业痛点诸多,制药研发周期长.生物技术创新协同难.医疗器械研发生产衔接不畅.医疗保健服务流程繁琐.Leangoo 可化解困境,促各领域信息共享.流程优化.协同增效,提升效率与质量,推动医药行业整体 ...
- 【2020.11.25提高组模拟】小 T 与灵石(stone) 题解
[2020.11.25提高组模拟]小 T 与灵石(stone) 题解 题意简述 给一棵根为\(1\)的树.一共\(q\)次操作,每次选\(k_i\)个节点\(p_1,p_2,\dots,p_{k_i} ...
- 【前端AI实践】泛谈AI实践:技术大牛们早就在用的AI在前端领域的场景
写代码有时候就像点外卖 -- 你得选对工具.用好方法,才能又快又好地解决问题.AI 就像是你编程路上的"厨房助手",帮你搞定重复劳动.理清逻辑.甚至还能给你提建议. 下面我们就从几 ...
- [书籍精读]《CSS世界》精读笔记分享
写在前面 书籍介绍:本书从前端开发人员的需求出发,以"流"为线索,从结构.内容到美化装饰等方面,全面且深入地讲解前端开发人员必须了解和掌握的大量的CSS知识点.同时,作者结合多年的 ...
- Function AI 工作流发布:以 AI 重塑企业流程自动化
AI 工作流如何重塑企业自动化流程 在 AI 技术飞速发展的今天,企业的流程自动化方式也正在发生深刻变革.过去,流程自动化往往依赖于人工配置和固定规则,难以适应复杂.多变的业务场景.而如今, 随着 L ...
- go-zero使用
官网文档地址: https://go-zero.dev/docs/tasks 这是一个脚手架,用于把proto文件或者api文件转为服务代码. 环境安装分4步(官网文档上有写): 1.安装golang ...
- 记一次ADL导致的C++代码编译错误
这篇文章主要讲讲c++的ADL,顺便说说为什么很多c++的IDE都会让你尽量不要include用不上的头文件. 和其他c++文章一样,这篇也会有基础回顾环节,所以不用担心看不懂,但读者最好还是得有c+ ...
- INNER JOIN, LEFT JOIN, RIGHT JOIN 的区别
今天我们来一起探索下 JOIN,JOIN 作为数据库操作的核心概念,用于合并两个或多个表中的数据. 一.JOIN (INNER JOIN) 1.基本功能:返回两个表中匹配成功的行. 2.特点: 只保留 ...