[atARC070E]NarrowRectangles
记$len_{i}=r_{i}-l_{i}$,即第$i$个区间的长度
用$f_{i,j}$表示前$i$个区间合法,第$i$个区间位于$[j,j+len_{i}]$的最小代价,暴力dp的时间复杂度为$o(nL^{2})$
考虑$f_{i,j}$的转移,即$f_{i,j}=\min_{[j,j+len_{i}]\cap[k,k+len_{i-1}]\ne \empty}f_{i-1,k}+|j-l_{i}|$
不难证明,这样的$k$是一段连续区间,可以表示为$[j-x,j+y]$($x,y\ge 0$)
接下来,对每一个$i$,若将$f_{i,j}$看成关于$j$的函数且用直线连结相邻点,那么可以证明其具有凸性
考虑归纳,更严谨的描述是:令$f'_{i,j}=f_{i,j}-f_{i,j+1}$,证明$f'_{i,j}$单调不递增
记$[x_{0},y_{0})$为$f'_{i,j}=0$的区间($[x,y]$就是$f_{i,j}$最小值的区间),根据凸性来考虑其最小值的位置——
1.$j\in [x_{0}-y,y_{0}+x]$,最小值位于$f_{i-1,x_{0}}$(即原来最小值)
2.$j<x_{0}-y$,最小值位于$f_{i-1,j-x}$
3.$j>y_{0}+x$,最小值位于$f_{i-1,j+y}$
可以发现,这等价于将$(-\infty,x_{0}]$向左移动$y$格,将$[y_{0},\infty)$向右移动$x$格,空出来的部分仍然取最小值
这是有凸性的,再加上一个绝对值函数,显然仍然具有凸性,因此即证明了该结论
考虑这件事情如何维护,记$a_{k}$为第小的$j$满足$f'_{i,j}\ge k$的$j$(特别的,$a_{i}=-\infty$),将$a[0,i)$与$a[-i,0)$分别用一个set维护,分别考虑移动和加入绝对值:
(不难发现$x_{0}=a_{0}$,$y_{0}=a_{-1}$)
1.移动是比较容易的,分别记录一个懒标记即可
2.考虑加入一个$|j-l_{i}|$,将其与$[x_{0},y_{0}]$分类讨论:
(1)$l_{i}\in [x_{0},y_{0})$,相当于将$a[0,i)$右移一位,之后加入$f'_{i,l_{i}}=-1$,即$a_{0}=a_{-1}=l_{i}$(其余位置由于用set维护,不需要实际去移动它);
(2)$l_{i}<x_{0}$,相当于将两个$l_{i}$(由于左加1自身减1会导致一个值不存在,也加到$l_{i}$上)加入左边的集合,并将$a_{0}$移动到右边
(3)$l_{i}>y_{0}$,类似的,即将两个$l_{i}$加入右边,并将$a_{-1}$移动到左边
关于最后的答案,不断维护最小值上的值即可


- 1 #include<bits/stdc++.h>
- 2 using namespace std;
- 3 #define N 100005
- 4 #define ll long long
- 5 multiset<ll>vl,vr;
- 6 int n,l[N],r[N];
- 7 ll tagl,tagr,ans;
- 8 int main(){
- 9 scanf("%d",&n);
- 10 for(int i=1;i<=n;i++)scanf("%d%d",&l[i],&r[i]);
- 11 vl.insert(l[1]);
- 12 vr.insert(l[1]);
- 13 for(int i=2;i<=n;i++){
- 14 int x=r[i-1]-l[i-1],y=r[i]-l[i];
- 15 tagl-=y;
- 16 tagr+=x;
- 17 ll x0=(*--vl.end())+tagl,y0=(*vr.begin())+tagr;
- 18 if ((x0<=l[i])&&(l[i]<y0)){
- 19 vl.insert(l[i]-tagl);
- 20 vr.insert(l[i]-tagr);
- 21 }
- 22 else{
- 23 if (l[i]<x0){
- 24 ans+=x0-l[i];
- 25 vl.insert(l[i]-tagl);
- 26 vl.insert(l[i]-tagl);
- 27 vl.erase(--vl.end());
- 28 vr.insert(x0-tagr);
- 29 }
- 30 else{
- 31 ans+=l[i]-y0;
- 32 vr.insert(l[i]-tagr);
- 33 vr.insert(l[i]-tagr);
- 34 vr.erase(vr.begin());
- 35 vl.insert(y0-tagl);
- 36 }
- 37 }
- 38 }
- 39 printf("%lld",ans);
- 40 }
[atARC070E]NarrowRectangles的更多相关文章
- AT2347 [ARC070C] NarrowRectangles
首先不难看出一个暴力的 \(dp\) 解法,考虑令 \(dp_{i, j}\) 表示考虑完前 \(i\) 个矩形,第 \(i\) 个矩形左端点在 \(j\) 时所需要的最小花费. 不难有转移: \[d ...
- 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的那部分需要减掉的那 ...
随机推荐
- MacOS上通过虚拟机搭建基础CentOS7系统环境
MacOS上通过虚拟机搭建基础CentOS7系统环境 尽管从Mac的Terminal可以看出,macOS与UNIX.Linux或多或少都有血缘关系(shell.bash等),但是在mac进行Linux ...
- 统计学习:线性支持向量机(SVM)
学习策略 软间隔最大化 上一章我们所定义的"线性可分支持向量机"要求训练数据是线性可分的.然而在实际中,训练数据往往包括异常值(outlier),故而常是线性不可分的.这就要求我们 ...
- Protocol handler start failed
问题描述: 启动项目的时候出现的中文大体意思是:协议处理程序启动失败看着这个启动失败,下意识就想是不是端口占用了,结果换个端口还是不行,于是百度了一个办法 问题解决: 打开任务管理器,找到Java的后 ...
- Pytorch——张量 Tensors
张量 Tensors 1.torch.is_tensor torch.is_tensor(obj) 用法:判断是否为张量,如果是 pytorch 张量,则返回 True. 参数:obj (Object ...
- pycharm安装第三方库
https://jingyan.baidu.com/article/4853e1e54b845e1909f7268f.html
- filebeat收集日志到elsticsearch中并使用ingest node的pipeline处理
filebeat收集日志到elsticsearch中 一.需求 二.实现 1.filebeat.yml 配置文件的编写 2.创建自定义的索引模板 3.加密连接到es用户的密码 1.创建keystore ...
- SpringCloud 2020.0.4 系列之服务降级的其他用法与熔断
1. 概述 老话说的好:控制好自己的情绪,才能控制好自己的人生.冲动是魔鬼,冷静才最重要. 言归正传,之前聊了在 Feign 调用时,如何给整个 Feign接口类 增加降级策略. 今天我们来聊一下 H ...
- 函数指针和qsort函数
1.函数指针的形式: 函数指针:int (*funcP) (int *a, int *b) 表示定义了一个funcP函数指针,指向了返回值为int类型,参数为int* 和int* 的函数 使用方式: ...
- RMQ、ST表
ST表 \(\text{ST}\) 表是用于解决可重复贡献问题的数据结构. 可重复贡献问题:区间按位和.区间按位或.区间 \(\gcd\) .区间最大.区间最小等满足结合律且可重复统计的问题. 模板预 ...
- Java:final,finally 和 finalize 的区别
在Java中,final,final和finalize之间有许多差异.final,final和finalize之间的差异列表如下: No final finally finalize 1 final用 ...