Luogu4655 [CEOI2017]Building Bridges
Luogu4655 [CEOI2017]Building Bridges
有 \(n\) 根柱子依次排列,每根柱子都有一个高度。第 \(i\) 根柱子的高度为 \(h_i\) 。
现在想要建造若干座桥,如果一座桥架在第 \(i\) 根柱子和第 \(j\) 根柱子之间,那么需要 \((h_i-h_j)^2\) 的代价。
在造桥前,所有用不到的柱子都会被拆除,因为他们会干扰造桥进程。第 \(i\) 根柱子被拆除的代价为 \(w_i\) 。
现在政府想要知道,通过桥梁把第 \(1\) 根柱子和第 \(n\) 根柱子连接的最小代价。注意桥梁不能在端点以外的任何地方相交。
\(n\leq10^5,\ 0\leq h_i,\ |w_i|\leq10^6\)
斜率优化,cdq分治
考虑计算所有拆除柱子的贡献,再在转移过程中消去
于是得到一个状态转移方程
\]
答案即为 \(f_n\)
于是就有了一个优秀的 \(O(n^2)\) 的过不去算法了
然而这玩意儿是可以斜率优化的
通过一番套路地化式子,可以得到
\]
令 \(h_j\) 为横坐标, \(f_j+h_j^2\) 为纵坐标, \(2h_i\) 为斜率
然后……可以发现 \(h_j\) 不是递增的……
这就意味着……需要支持插入,询问前驱后继,以及一些复杂的分类讨论……
我会平衡树维护动态凸包!
然而有更好的离线解决办法:cdq分治
强制让斜率递增然后计算贡献
回想cdq分治的过程,左右递归,计算左侧对右侧的贡献
如果左侧斜率递增,并且左侧编号小于右侧,那么可以通过单调队列维护左侧的凸包来更新右侧答案
并且这样一定能够遍历出每个节点的所有决策点
注意 \(long\ long\) ,以及求斜率时 \(x_1=x_2\) 的情况
时间复杂度 \(O(n\log n)\)
代码
#include <bits/stdc++.h>
using namespace std;
typedef double db;
typedef long long ll;
const int maxn = 1e5 + 10;
ll f[maxn];
int n, w[maxn];
struct node {
int x, tid; ll y;
} a[maxn], dat[maxn];
ll sqr(ll x) { return x * x; }
db slope(int x, int y) {
if (a[x].x == a[y].x) {
return a[x].y < a[y].y ? 1e18 : -1e18;
}
return db(a[x].y - a[y].y) / db(a[x].x - a[y].x);
}
void cdq(int l, int r) {
if (l == r) {
a[l].y = f[a[l].tid] + sqr(a[l].x);
return;
}
int mid = (l + r) >> 1;
for (int i = l, p1 = l, p2 = mid + 1; i <= r; i++) {
if (a[i].tid <= mid) {
dat[p1++] = a[i];
} else {
dat[p2++] = a[i];
}
}
for (int i = l; i <= r; i++) {
a[i] = dat[i];
}
cdq(l, mid);
int L = 1, R = 0;
static int q[maxn];
for (int i = l; i <= mid; i++) {
while (L < R && slope(q[R - 1], q[R]) > slope(q[R], i)) R--;
q[++R] = i;
}
for (int i = mid + 1; i <= r; i++) {
while (L < R && slope(q[L], q[L + 1]) < 2 * a[i].x) L++;
int x = a[i].tid, y = a[q[L]].tid;
f[x] = min(f[x], f[y] + sqr(a[i].x - a[q[L]].x) - w[x]);
}
cdq(mid + 1, r);
for (int i = l, p1 = l, p2 = mid + 1; i <= r; i++) {
if (p2 > r || (p1 <= mid && a[p1].x < a[p2].x)) {
dat[i] = a[p1++];
} else {
dat[i] = a[p2++];
}
}
for (int i = l; i <= r; i++) {
a[i] = dat[i];
}
}
int main() {
scanf("%d", &n);
for (int i = 1; i <= n; i++) {
scanf("%d", &a[i].x);
a[i].tid = i, f[i] = 1ll << 60;
}
f[1] = 0;
for (int i = 1; i <= n; i++) {
scanf("%d", w + i);
if (i > 1) f[1] += w[i];
}
sort(a + 1, a + n + 1, [](node a, node b) {
return a.x < b.x;
});
cdq(1, n);
printf("%lld", f[n]);
return 0;
}
2019.4.30 upd: 我发现这玩意儿好像是WC2013被提出来的……
Luogu4655 [CEOI2017]Building Bridges的更多相关文章
- 题解-[CEOI2017]Building Bridges
[CEOI2017]Building Bridges 有 \(n\) 个桥墩,高 \(h_i\) 重 \(w_i\).连接 \(i\) 和 \(j\) 消耗代价 \((h_i-h_j)^2\),用不到 ...
- 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. 「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: 洛谷 P4655: 「CEOI2017」Building Bridges
题目传送门:LOJ #2483. 题意简述: 有 \(n\) 个数,每个数有高度 \(h_i\) 和价格 \(w_i\) 两个属性. 你可以花费 \(w_i\) 的代价移除第 \(i\) 个数(不能移 ...
- @loj - 2483@「CEOI2017」Building Bridges
目录 @desription@ @solution@ @accepted code@ @details@ @another solution@ @another code@ @desription@ ...
随机推荐
- HNOI2019 苟命记
Day0 瞎看了看博客,然后看了看wf题,看了一下午柯南剧场版... 后来发现,复习根本没用,因为我根本没学过. Day1 首先随便看了看三道题,觉得 \(T1\) 挺可做的,\(T2\) 看起来是什 ...
- 【死磕 Spring】----- IOC 之 获取验证模型
原文出自:http://cmsblogs.com 在上篇博客[死磕Spring]----- IOC 之 加载 Bean 中提到,在核心逻辑方法 doLoadBeanDefinitions()中主要是做 ...
- 关于Layer ui的加载层位置居中问题
最近在项目中一直使用layerui的相应的提示框以及它的加载层,然而就在今天遇到了一个神奇的问题,我使用 var index = layer.load(0, {shade: false}); 结果一直 ...
- Go语言strings包
目录 strings包实现了用于操作字符的简单函数. func EqualFold 判断两个utf-8编码字符串(将unicode大写.小写.标题三种格式字符视为相同)是否相同. func Equal ...
- .NET Core微服务之基于Ocelot实现API网关服务(续)
Tip: 此篇已加入.NET Core微服务基础系列文章索引 一.负载均衡与请求缓存 1.1 负载均衡 为了验证负载均衡,这里我们配置了两个Consul Client节点,其中ClientServic ...
- 推荐系统(Recommendation system )介绍
前言 随着电子商务的发展,网络购物成为一种趋势,当你打开某个购物网站比如淘宝.京东的时候,会看到很多给你推荐的产品,你是否觉得这些推荐的产品都是你似曾相识或者正好需要的呢.这个就是现在电子商务里面的推 ...
- springcloud~Eureka实例搭建
服务端 build.gradle配置 dependencies { compile('org.springframework.cloud:spring-cloud-starter-netflix-eu ...
- springboot~maven制作底层公用库
把一些公用方法,类型抽象到一个项目里,让其它项目依赖它,这种设计是一种解耦的体现,其实像springboot就是我们的一种依赖,他里面有很多子模块,用到哪个就添加哪个依赖即可,像redis,mongo ...
- 用消息队列和socket实现聊天系统
前言:最近在学进程间通信,所以做了一个小项目练习一下.主要用消息队列和socket(UDP)实现这个系统,并数据库存储数据,对C语言操作不熟悉的可以参照我的这篇博客:https://www.cnblo ...
- RESTful 规范
RESTful 规范 前言 rest 是一种软件架构风格,如果使用的是 rest 接口,那么就可以说你的接口是 restful. rest接口是围绕''资源''展开的,利用 HTTP 的协议,其实 r ...