AT2347 [ARC070C] NarrowRectangles
首先不难看出一个暴力的 \(dp\) 解法,考虑令 \(dp_{i, j}\) 表示考虑完前 \(i\) 个矩形,第 \(i\) 个矩形左端点在 \(j\) 时所需要的最小花费。
不难有转移:
\]
继续考虑对上面这个 \(dp\) 进行优化,可以发现的是,这个 \(dp\) 本质上是在对之前的某个区域取 \(\min\) 然后再加上一个之和每个位置有关的绝对值函数。
看起来十分抽象,那么我们可以考虑把抽象问题具体化,将 \(dp_i\) 看作是一个关于 \(j\) 的函数,再来考虑一下转移。
从初始的 \(i = 1\) 开始考虑,不难发现 \(dp_1\) 就是 \(y = |j - l_1|\) 这样一个绝对值函数。
再来考虑 \(i = 2\) 的情况,可以发现前一步取 \(\min\) 本质上是将这个绝对值函数的左段向左平移了 \(r_i - l_i\),右段向右平移了 \(r_{i - 1} - l_{i - 1}\),中间用一段斜率为 \(0\) 的线段接起来。
再来考虑加入 \(|j - l_i|\) 这个绝对值函数,不难发现图像的变化需要分三种情况,但整体的变化方式都是确定的,即 :
- \(l_i\) 左边的函数斜率整体 \(-1\) 右边的函数斜率整体 \(+1\),同时斜率变化的点的横坐标不变。
可以发现,这样变化后的图像一定还是一个下凸包。
那么就不难通过归纳证明每次转移的过程都是类似于 \(i = 2\) 的情况的。
同时,因为每一个函数 \(dp_i\) 的斜率最大最小值都不会超过 \(\pm |2i - 1|\),因此我们可以考虑直接维护这些斜率变化的拐点。
为了方便起见,如果在这个拐点斜率变化了 \(k\),我们就直接插 \(k\) 个这个点进去代表斜率变化了 \(k\) 个 \(1\)。
首先,因为左右两个函数的平移是不同的,因此我们要分开维护左右两边的断点。
并且,因为函数只是平移,因此我们只需要记录当前平移了多长的距离即可,下面着重来考虑加入一个绝对值函数的过程。
- 当插入的绝对值函数零点在图像斜率为 \(0\) 的那段上时。
不难发现左边之前的拐点还是拐点,右边亦然。唯一变化的是左边右都会要在 \(l_i\) 处添加一个拐点。
- 当插入的绝对值函数零点在图像斜率为 \(0\) 的那段左边时。
不难发现此时左边会在 \(l_i\) 处添加两个拐点,同时失去最靠右的拐点,右边会得到左边失去的哪个拐点。(注意这里的拐点实际上代表着斜率变化为 \(1\),这样就方便地处理掉左边做靠右的直线斜率不为 \(-1\) 的情况了)
因为需要取出最右边的端点,因此我们需要一个大根堆来维护左边的拐点。
- 当插入的绝对值函数零点在图像斜率为 \(0\) 的那段右边时。
同理于上一种情况,用小根堆维护右边的拐点。
那么最终的答案是什么呢?
不难发现其实是最终 \(dp_n\) 斜率为 \(0\) 的那段函数对应的纵坐标。
但是我们并没有记录每一次的纵坐标,怎么办呢?
你会发现每次斜率为 \(0\) 的直线位置总是会向右或者向左变化,而这两次斜率为 \(0\) 的直线中会存在一个交点。
同时因为对于每一层而言,取斜率为 \(0\) 线段上的点总是最优的。
结合上面那条性质,每次选定一个斜率为 \(0\) 的线段做为这一层的 \(j\) 即可,然后计算答案只要计算往下一层斜率为 \(0\) 交点纵坐标的变化量即可。
#include <bits/stdc++.h>
using namespace std;
#define int long long
#define rep(i, l, r) for (int i = l; i <= r; ++i)
const int N = 1e5 + 5;
int n, l, r, nL, nR, TL, TR, len, ans, lastlen;
priority_queue <int> L;
priority_queue <int, vector <int>, greater <int> > R;
int read() {
char c; int x = 0, f = 1;
c = getchar();
while (c > '9' || c < '0') { if(c == '-') f = -1; c = getchar();}
while (c >= '0' && c <= '9') x = x * 10 + c - '0', c = getchar();
return x * f;
}
signed main() {
n = read(), l = read(), r = read();
L.push(l), R.push(l), lastlen = r - l;
for (int i = 2; i <= n; ++i, lastlen = len) {
l = read(), r = read(), len = r - l, TL += len, TR += lastlen;
nL = L.top() - TL, nR = R.top() + TR;
if(l < nL) ans += nL - l, L.pop(), R.push(nL - TR), L.push(l + TL), L.push(l + TL);
else if(l > nR) ans += l - nR, R.pop(), L.push(nR + TL), R.push(l - TR), R.push(l - TR);
else L.push(l + TL), R.push(l - TR);
}
printf("%lld", ans);
return 0;
}
这种方法被称为 \(\rm set\) 维护函数拐点,经常用与维护一次分段函数的变化问题。
AT2347 [ARC070C] NarrowRectangles的更多相关文章
- [atARC070E]NarrowRectangles
记$len_{i}=r_{i}-l_{i}$,即第$i$个区间的长度 用$f_{i,j}$表示前$i$个区间合法,第$i$个区间位于$[j,j+len_{i}]$的最小代价,暴力dp的时间复杂度为$o ...
- AtCoder 杂题训练
前言: 因为要普及了,今年没一等就可以退役去学文化课了,所以暑假把历年noip普及组都刷了一遍,离noip还有50+天,想弄点强化训练什么的. 想了想,就这些天学文化课之余有空就把AtCoder之前那 ...
- AtCoder刷题记录
构造题都是神仙题 /kk ARC066C Addition and Subtraction Hard 首先要发现两个性质: 加号右边不会有括号:显然,有括号也可以被删去,答案不变. \(op_i\)和 ...
- 【AtCoder】ARC070
ARC070 C - Go Home 题目大意:一只袋鼠第i秒可以向左或向右跳i步或者不跳,问从0跳到x的最小时间 就是1,2,3,4...k总和超过x的最小的k,因为如果超过了x的那部分需要减掉的那 ...
随机推荐
- POJ 3126:Prime Path(素数+BFS)
The ministers of the cabinet were quite upset by the message from the Chief of Security stating that ...
- IntelliJ IDEA打war包
1.按ctrl+alt+shift+s键打开Project Structure,点击+号图标,选择"Artifacts->Web Application Archive" 2 ...
- 【环境搭建】安装pyQt5 在pycharm报This application failed to start because no Qt platform plugin could be initialized的问题
报错:This application failed to start because no Qt platform plugin could be initialized 解决办法: http:// ...
- C语言string操作
创建方式 字符数组:空间已定 字符指针:未分配空间 初始化 字符数组: 创建与赋值必须在同一行 指定大小:未填满部分用'\0'填充 用字符串初始化:末尾自动添加'\0' 不初始化赋值则乱值 字符指针: ...
- .NET6: 三分钟搭建WPF三维应用
要运行本文中的示例,请先安装Vistual Studio 2022,社区版就可以了. 1 创建项目 选择创建WPF应用 给程序起一个酷酷的名字,选一个酷酷的位置: 选一下.NET6 2 配置项目 从n ...
- 云南农业职业技术学院 - 互联网技术学院 - 美和易思《MYSQL 高级查询与编程》 综合机试试卷
数据库及试题文档下载:https://download.csdn.net/download/weixin_44893902/14503097 目录 题目:电商平台 mysql 数据库系统管理 一. 语 ...
- Typescript 字符串字面量类型
字符串字面类型定义的类型是固定的,在其使用时必须是其定义的其中一个字符串,否则会报错 当传入一个定义之外的字符串时,会报错字符串字面量类型.ts(13,20): error TS2345: Argum ...
- PowerShell【变量篇】
PS C:\Users\Administrator> $str='这是一个变量' PS C:\Users\Administrator> $str 这是一个变量 PS C:\Users\Ad ...
- javascript错误类型
ECMA-262 定义了下列 7 种错误类型,简单说明如下: Error:普通异常.通常与 throw 语句和 try/catch 语句一起使用. 利用属性 name 可以声明或了 解异常的类型,利用 ...
- LINUX学习--nginx服务器的安装
一.安装环境 操作系统CentOS6.8 关闭SeLinux和iptables防火墙 二.网络yum源 将下面的软件下载到 /etc/yum.repos.d/ 的目录下 官方基础:http:// ...