[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的那部分需要减掉的那 ...
随机推荐
- MySQL5.7主从复制-异步复制搭建
两台服务器,系统是Redhat6.5,MySQL版本是5.7.18.1.在主库上,创建复制使用的用户,并授予replication slave权限.这里创建用户repl,可以从IP为10.10.10 ...
- 技术番外篇丨Github Action CI/CD
起源 看到.Net群里再聊CI/CD,我就这里分享一下我目前自己一些小东西的做法,我目前在Github有一个自己私有的组织,里面存放了我的部分商业化项目,早期我采用Jenkins用Webhooks进行 ...
- 题解 「SDOI2017」硬币游戏
题目传送门 Description 周末同学们非常无聊,有人提议,咱们扔硬币玩吧,谁扔的硬币正面次数多谁胜利. 大家纷纷觉得这个游戏非常符合同学们的特色,但只是扔硬币实在是太单调了. 同学们觉得要加强 ...
- 题解 Sue的小球/名次排序问题/方块消除/奥运物流
Sue的小球 名次排序问题 方块消除 奥运物流 Sue的小球 题目大意 有 \(n\) 个小球在下落,初始位置 \((x_i,y_i)\),下落速度为 \(v_i\).你初始位置在 \(x_0\),速 ...
- C 函数指针 函数指针数组 转移表
内容来自<c和指针>,整理后方便个人理解 高级声明 cdel程序可以方便的给出声明的释义 指向函数的指针 int ( *f ) ( int n_values, float amount ) ...
- gitk
gitk gitk [<options>] [<revision range>] [--] [<path>-] 查看单个文件的变更历史 gitk -- CppPri ...
- 笨方法学python中执行argv提示ValueError: not enough values to unpack (expected 4, got 1)
解决方法:选择Terminal中输入执行ex13.py 1 2 3 执行结果如下图
- 【二食堂】Beta - Scrum Meeting 7
Scrum Meeting 7 例会时间:5.19 18:30~18:50 进度情况 组员 当前进度 今日任务 李健 1. 文本区域的前后端对接完成,bug已经修复issue2. 自定义关系的添加与删 ...
- stm32电机控制之控制两路直流电机!看完你会了吗
手头上有一个差分驱动的小车,使用两个直流电机驱动,要实现小车的在给定速度下运动,完成直线行驶,转向,加速,刹车等复杂运动. 使用的电机是12v供电的直流电机,带编码器反馈,这样就可以采用闭环速度控制, ...
- Java设计模式——模板设计模式
模板设计模式 1.模板模式简介 模板模式(Template ):模板方法模式是类的行为模式.准备一个抽象类,将部分逻辑以具体方法以及具体构造函数的形式实现,然后声明一些抽象方法来迫使子类实现剩余的逻辑 ...