题解-[CEOI2017]Building Bridges
有 \(n\) 个桥墩,高 \(h_i\) 重 \(w_i\)。连接 \(i\) 和 \(j\) 消耗代价 \((h_i-h_j)^2\),用不到的桥墩被拆除,代价为 \(w_i\)。求使 \(1\) 与 \(n\) 联通的最小代价。
数据范围:\(2\le n\le 10^5\),\(0\le h_i,|w_i|\le 10^6\)。
非常经典的李超线段树维护 \(\texttt{dp}\) 的题目,小蒟蒻来分享一下。
很明显 \(w_i\) 是大片大片消耗的,所以记 \(s_i=\sum_{j=1}^i w_j\)。
令 \(f_i\) 表示连接到第 \(i\) 个桥墩的最小代价。可以野蛮推式:
f_i=&\min\{f_j+(h_i-h_j)^2+s_{i-1}-s_j\}\\
=&\min\{f_j+h_i^2-2h_ih_j+h_j^2+s_{i-1}-s_j\}\\
=&h_i^2+s_{i-1}+\min\{f_j-2h_ih_j+h_j^2-s_j\}\\
\end{split}\\
\]
这貌似是个斜率优化式子,但蒟蒻不管,用李超线段树怎么做呢?
考虑李超线段树的作用:多条线段(直线),求单点最值。
发现这个 \(j\) 有很多,而 \(i\) 就只有当前一个:所以可以 \(i\) 对应单点,\(j\) 对应线。换句话说,可以把每个 \(f_i\) 求出来后添加一条直线。
\textrm{let } x=h_i \textrm{ to get }\min\{f_j-2h_ih_j+h_j^2-s_j\}\textrm{.}\\
\]
这题有几个坑,本来是应该由你来快乐地调试的,但是既然写了题解,蒟蒻就放出来了:
- 因为要计算 \(h_j^2\),所以要开 \(\texttt{long long}\) 或用 \(1ll\) 乘之。
- 这个李超线段树是权值线段树,下标要开 \(10^6\) 个,节点个数要开 \(4\cdot 10^6\) 个。
这个做法貌似有点辜负了这题的难度,但是蒟蒻只会这么做。蒟蒻讲不清楚,还是放个蒻蒻的代码吧:
#include <bits/stdc++.h>
using namespace std;
//Start
#define lng long long
#define db double
#define mk make_pair
#define pb push_back
#define fi first
#define se second
#define rz resize
const int inf=0x3f3f3f3f;
const lng INF=0x3f3f3f3f3f3f3f3f;
//Data
const int N=1e5,M=1e6;
int n,h[N+7];
lng w[N+7],f[N+7];
//Lichaotree
typedef pair<lng,lng> line;
lng g(line&li,int x){return li.fi*x+li.se;}
int inter(line&la,line&lb){return db(lb.se-la.se)/(la.fi-lb.fi);}
line v[(M<<2)+7];
void add(line li,int k=1,int l=0,int r=M){
int mid((l+r)>>1);
lng ly1=g(li,l),ry1=g(li,r),ly=g(v[k],l),ry=g(v[k],r);
if(ly1>=ly&&ry1>=ry);
else if(ly1<=ly&&ry1<=ry) v[k]=li;
else {
int in=inter(li,v[k]);
if(ly1<=ly){
if(in<=mid) add(li,k<<1,l,mid);
else add(v[k],k<<1|1,mid+1,r),v[k]=li;
} else {
if(in>mid) add(li,k<<1|1,mid+1,r);
else add(v[k],k<<1,l,mid),v[k]=li;
}
}
}
lng get(int x,int k=1,int l=0,int r=M){
lng res(g(v[k],x));
if(l==r) return res;
int mid((l+r)>>1);
if(mid>=x) res=min(res,get(x,k<<1,l,mid));
else res=min(res,get(x,k<<1|1,mid+1,r));
return res;
}
//Main
int main(){
scanf("%d",&n);
for(int i=1;i<=n;i++) scanf("%d",&h[i]);
for(int i=1;i<=n;i++) scanf("%lld",&w[i]),w[i]+=w[i-1];
fill(v+1,v+(M<<2)+1,mk(0,INF));
f[1]=0,add(mk(-2ll*h[1],1ll*h[1]*h[1]-w[1]));
for(int i=2;i<=n;i++){
f[i]=1ll*h[i]*h[i]+w[i-1]+get(h[i]);
add(mk(-2ll*h[i],f[i]+1ll*h[i]*h[i]-w[i]));
}
printf("%lld\n",f[n]);
return 0;
}
祝大家学习愉快!
题解-[CEOI2017]Building Bridges的更多相关文章
- Luogu4655 [CEOI2017]Building Bridges
Luogu4655 [CEOI2017]Building Bridges 有 \(n\) 根柱子依次排列,每根柱子都有一个高度.第 \(i\) 根柱子的高度为 \(h_i\) . 现在想要建造若干座桥 ...
- ceoi2017 Building Bridges(build)
Building Bridges(build) 题目描述 A wide river has nn pillars of possibly different heights standing out ...
- 洛谷.4655.[CEOI2017]Building Bridges(DP 斜率优化 CDQ分治)
LOJ 洛谷 \(f_i=s_{i-1}+h_i^2+\min\{f_j-s_j+h_j^2-2h_i2h_j\}\),显然可以斜率优化. \(f_i-s_{i-1}-h_i^2+2h_ih_j=f_ ...
- [CEOI2017]Building Bridges
题目 斜率优化思博题,不想写了 之后就一直\(95\)了,于是靠肮脏的打表 就是更新了一下凸壳上二分斜率的写法,非常清爽好写 就当是挂个板子了 #include<algorithm> #i ...
- loj#2483. 「CEOI2017」Building Bridges 斜率优化 cdq分治
loj#2483. 「CEOI2017」Building Bridges 链接 https://loj.ac/problem/2483 思路 \[f[i]=f[j]+(h[i]-h[j])^2+(su ...
- HDU 4584 Building bridges (水题)
Building bridges Time Limit: 3000/1000 MS (Java/Others) Memory Limit: 65535/32768 K (Java/Others) ...
- LOJ 2483: 洛谷 P4655: 「CEOI2017」Building Bridges
题目传送门:LOJ #2483. 题意简述: 有 \(n\) 个数,每个数有高度 \(h_i\) 和价格 \(w_i\) 两个属性. 你可以花费 \(w_i\) 的代价移除第 \(i\) 个数(不能移 ...
- loj#2483. 「CEOI2017」Building Bridges(dp cdq 凸包)
题意 题目链接 Sol \[f[i], f[j] + (h[i] - h[j])^2 + (w[i - 1] - w[j]))\] 然后直接套路斜率优化,发现\(k, x\)都不单调 写个cdq就过了 ...
- @loj - 2483@「CEOI2017」Building Bridges
目录 @desription@ @solution@ @accepted code@ @details@ @another solution@ @another code@ @desription@ ...
随机推荐
- 1. 线性DP 53. 最大子序和.
53. 最大子序和. https://leetcode-cn.com/problems/maximum-subarray/ func maxSubArray(nums []int) int { dp ...
- tar命令打包和压缩与解压
Linux里压缩与打包时分开的: 打包:多个文件变一个文件.该一个文件会大于整体所有文件,因为会添加各个信息说明哪到哪是一个文件. 压缩:大文件变小文件. 归档:将多个文件变成一个文件,这个文件就是归 ...
- Mysql数据安全备份
数据安全备份的意义 在出现意外的时候(硬盘损坏.断点.黑客攻击),以便数据的恢复 导出生产的数据以便研发人员或者测试人员测试学习 高权限的人员那操作失误导致数据丢失,以便恢复 备份类型 完全备份:对整 ...
- docker漏洞复现环境搭建
0x00 docker简介 把原来的笔记整理了一下,结合前几天的一个漏洞,整理一篇简单的操作文档,希望能帮助有缘人. docker是一个开源的应用容器引擎,开发者可以打包自己的应用到容器里面,然后迁移 ...
- unctf2020 部分简单题题解
unctf2020 水一波简单题..菜狗前来报道..大佬轻喷..如果有时间做题就好了呜呜呜 misc 1.baba_is_you 题目告诉我们,了解png文件格式. 下载得到一张png格式的图片. 用 ...
- 【硬件】HDMI接口HPD原理
目录 一.什么是HPD? 二.HDMI的HPD(热插拔)原理 三.HDMI源端对HPD信号有什么要求? 由于项目需要通过HDMI获取EDID的数据,需要学习一下其获取的工作原理,所以在这里记录下. 一 ...
- 企业级工作流解决方案(十一)--集成Abp和ng-alain--权限系统服务
权限系统主要定义为管理员增删改查权限数据,直接读取数据库,权限系统服务主要定义为供其他系统调用的权限验证接口,定义为两个不同的微服务. 权限系统有一个特点,数据变动比较小,数据量本身并不是很大,访问量 ...
- ABBYY FineReader 14新建任务窗口给我们哪些帮助?
当您启动ABBYY FineReader时, 新任务 将打开一个窗口,在其中您可以轻松打开.扫描.创建或对比文档. 如果您没有看到此 内置任务 窗口(比如,如果您关闭了该窗口,或者您通过在 Windo ...
- 使用ABBYY FineReader 手动校正文档复杂结构
ABBYY FineReader 15(Windows系统)拥有强大的OCR识别功能,能对扫描仪或者数码相机等光学工具获取的图像进行识别,解析其中的文本.图像.表格.条形码等,方便用户进一步获取图像中 ...
- FLstudio 系列教程(七):FL Studio五大常用按钮介绍
我们打开FL Studio编曲软件会发现界面中有好多的菜单和窗口,这些窗口每个都有其单独的功能.今天小编主要给大家详细讲解下FL Studio水果软件的五大常用按钮. 1.首先我,我们双击桌面的水果图 ...