#李超线段树 or 斜率优化+CDQ分治#洛谷 4655 [CEOI2017]Building Bridges
分析
列出方程即为\(dp[i]=\min\{dp[j]+(h[i]-h[j])^2+s[i-1]-s[j]\}\)
\(dp[j]+h[j]^2-s[j]=2*h[i]*h[j]+dp[i]-s[i-1]-h[i]^2\)
那这就是一个斜率为\(2*h[i]\),截距为\(dp[i]-s[i-1]-h[i]^2\)的直线
那要使截距尽量小,考虑用李超线段树解决
否则由于\(h[i]\)不具有单调性,考虑CDQ分治,第一维是时间,第二维是\(h\),斜率优化做
代码(李超线段树)
#include <cstdio>
#include <cctype>
#define rr register
using namespace std;
typedef long long lll;
const int N=100011,M=1000011;
struct rec{lll a,b;}line[N];
lll h[N],s[N],dp[N]; int p[N*40],n;
inline signed iut(){
rr int ans=0,f=1; rr char c=getchar();
while (!isdigit(c)) f=(c=='-')?-f:f,c=getchar();
while (isdigit(c)) ans=(ans<<3)+(ans<<1)+(c^48),c=getchar();
return ans*f;
}
inline void print(lll ans){
if (ans<0) putchar('-'),ans=-ans;
if (ans>9) print(ans/10);
putchar(ans%10+48);
}
inline lll calc(int t,int x){return line[t].a*x+line[t].b;}
inline signed either(int t1,int t2,int x){return calc(t1,x)<calc(t2,x)?t1:t2;}
inline void update(int k,int l,int r,int x,int y,int z){
rr int mid=(l+r)>>1;
if (x<=l&&r<=y){
if (!p[k]) {p[k]=z; return;}
rr lll la=calc(p[k],l),lb=calc(z,l);
rr lll ra=calc(p[k],r),rb=calc(z,r);
if (la<=lb&&ra<=rb) return;
if (la>=lb&&ra>=rb){p[k]=z; return;}
rr double pos=(line[p[k]].b-line[z].b)*1.0/(line[z].a-line[p[k]].a);
if (la>=lb){
if (pos<=mid) update(k<<1,l,mid,x,y,z);
else update(k<<1|1,mid+1,r,x,y,p[k]),p[k]=z;
}else{
if (pos>mid) update(k<<1|1,mid+1,r,x,y,z);
else update(k<<1,l,mid,x,y,p[k]),p[k]=z;
}
return;
}
if (x<=mid) update(k<<1,l,mid,x,y,z);
if (mid<y) update(k<<1|1,mid+1,r,x,y,z);
}
inline signed query(int k,int l,int r,int x){
if (l==r) return p[k];
rr int mid=(l+r)>>1;
if (x<=mid) return either(p[k],query(k<<1,l,mid,x),x);
else return either(p[k],query(k<<1|1,mid+1,r,x),x);
}
signed main(){
n=iut(),line[0]=(rec){0,1000000000000000000ll};
for (rr int i=1;i<=n;++i) h[i]=iut();
for (rr int i=1;i<=n;++i) s[i]=s[i-1]+iut();
dp[1]=0,line[1]=(rec){-h[1]<<1,h[1]*h[1]-s[1]},update(1,0,M,0,M,1);
for (rr int i=2;i<=n;++i){
dp[i]=h[i]*h[i]+s[i-1]+calc(query(1,0,M,h[i]),h[i]);
line[i]=(rec){-h[i]<<1,dp[i]+h[i]*h[i]-s[i]},update(1,0,M,0,M,i);
}
return !printf("%lld",dp[n]);
}
代码(斜率优化)
#include <cstdio>
#include <cctype>
#include <cstring>
#include <algorithm>
#define rr register
using namespace std;
typedef long long lll;
const int N=100011; const lll inf=1ll<<60;
int X[N],h[N],a[N],n,b[N],q[N]; lll s[N],dp[N],Y[N];
inline signed iut(){
rr int ans=0,f=1; rr char c=getchar();
while (!isdigit(c)) f=(c=='-')?-f:f,c=getchar();
while (isdigit(c)) ans=(ans<<3)+(ans<<1)+(c^48),c=getchar();
return ans*f;
}
inline lll O(int x){return 1ll*x*x;}
inline lll min(lll a,lll b){return a<b?a:b;}
bool cmp(int x,int y){return h[x]<h[y];}
inline double slope(int i,int j){return (X[i]==X[j])?(Y[j]>=Y[i]?inf:-inf):((double)(Y[j]-Y[i])/(X[j]-X[i]));}
inline void cdq(int l,int r){
if (l==r){
Y[a[l]]=dp[a[l]]+O(h[a[l]])-s[a[l]];
return;
}
rr int mid=(l+r)>>1,i1=l,j1=mid+1;
for (rr int i=l;i<=r;++i)
if (a[i]<=mid) b[i1++]=a[i];
else b[j1++]=a[i];
for (rr int i=l;i<=r;++i) a[i]=b[i];
cdq(l,mid);
rr int head=1,tail=0,t=l-1;
for (rr int i=l;i<=mid;++i){
while (head<tail&&slope(q[tail-1],q[tail])>=slope(q[tail],a[i])) --tail;
q[++tail]=a[i];
}
for (rr int i=mid+1,I=a[i];i<=r;I=a[++i]){
while (head<tail&&slope(q[head],q[head+1])<=2*h[I]) ++head;
if (head<=tail) dp[I]=min(dp[I],dp[q[head]]+O(h[I]-h[q[head]])+s[I-1]-s[q[head]]);
}
cdq(mid+1,r);
for (i1=l,j1=mid+1;i1<=mid&&j1<=r;)
if (X[a[i1]]<X[a[j1]]) b[++t]=a[i1++];
else b[++t]=a[j1++];
while (i1<=mid) b[++t]=a[i1++];
while (j1<=r) b[++t]=a[j1++];
for (rr int i=l;i<=r;++i) a[i]=b[i];
}
signed main(){
n=iut(),memset(dp,0x3f,sizeof(dp));
for (rr int i=1;i<=n;++i) h[i]=iut();
for (rr int i=1;i<=n;++i) s[i]=s[i-1]+iut();
for (rr int i=1;i<=n;++i) X[i]=h[i],a[i]=i;
sort(a+1,a+1+n,cmp),dp[1]=0,cdq(1,n);
return !printf("%lld",dp[n]);
}
#李超线段树 or 斜率优化+CDQ分治#洛谷 4655 [CEOI2017]Building Bridges的更多相关文章
- 洛谷.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_ ...
- 【BZOJ3672】【NOI2014】购票(线段树,斜率优化,动态规划)
[BZOJ3672][NOI2014]购票(线段树,斜率优化,动态规划) 题解 首先考虑\(dp\)的方程,设\(f[i]\)表示\(i\)的最优值 很明显的转移\(f[i]=min(f[j]+(de ...
- BZOJ_3963_[WF2011]MachineWorks_斜率优化+CDQ分治
BZOJ_3963_[WF2011]MachineWorks_斜率优化+CDQ分治 Description 你是任意性复杂机器公司(Arbitrarily Complex Machines, ACM) ...
- 「线段树」「单点修改」洛谷P1198 [JSOI2008]最大数
「线段树」「单点修改」洛谷P1198 [JSOI2008]最大数 题面描述 现在请求你维护一个数列,要求提供以下两种操作: 1. 查询操作. 语法:Q L 功能:查询当前数列中末尾L个数中的最大的数, ...
- [Noi2014]购票 BZOJ3672 点分治+斜率优化+CDQ分治
Description 今年夏天,NOI在SZ市迎来了她30周岁的生日.来自全国 n 个城市的OIer们都会从各地出发,到SZ市参加这次盛会.全国的城市构成了一棵以SZ市为根的有根树,每个城市与它的 ...
- 【BZOJ-1492】货币兑换Cash DP + 斜率优化 + CDQ分治
1492: [NOI2007]货币兑换Cash Time Limit: 5 Sec Memory Limit: 64 MBSubmit: 3396 Solved: 1434[Submit][Sta ...
- BZOJ3963 WF2011MachineWorks(动态规划+斜率优化+cdq分治)
按卖出时间排序后,设f[i]为买下第i台机器后的当前最大收益,则显然有f[i]=max{f[j]+gj*(di-dj-1)+rj-pi},且若此值<0,应设为-inf以表示无法购买第i台机器. ...
- bzoj1492/luogu4027 货币兑换 (斜率优化+cdq分治)
设f[i]是第i天能获得的最大钱数,那么 f[i]=max{在第j天用f[j]的钱买,然后在第i天卖得到的钱,f[i-1]} 然后解一解方程什么的,设$x[j]=\frac{F[j]}{A[j]*Ra ...
- [BZOJ1492][NOI2007]货币兑换Cash(斜率优化+CDQ分治)
1492: [NOI2007]货币兑换Cash Time Limit: 5 Sec Memory Limit: 64 MBSubmit: 5838 Solved: 2345[Submit][Sta ...
- 【BZOJ2726】[SDOI2012]任务安排 斜率优化+cdq分治
[BZOJ2726][SDOI2012]任务安排 Description 机器上有N个需要处理的任务,它们构成了一个序列.这些任务被标号为1到N,因此序列的排列为1,2,3...N.这N个任务被分成若 ...
随机推荐
- 【LeetCode二叉树#10】从中序与后序(或者前序)遍历序列构造二叉树(首次构造二叉树)
从中序与后序遍历序列构造二叉树 力扣题目链接(opens new window) 根据一棵树的中序遍历与后序遍历构造二叉树. 注意: 你可以假设树中没有重复的元素. 例如,给出 中序遍历 inorde ...
- 【LeetCode哈希表#1】有效的字母异位词+赎金信(数组)
有效的字母异位词 力扣题目链接(opens new window) 给定两个字符串 s 和 t ,编写一个函数来判断 t 是否是 s 的字母异位词. 示例 1: 输入: s = "anagr ...
- 【Java复健指南02】方法的注意事项
[方法] 方法基本内容 √访问修饰符 (作用是控制方法使用的范围) 可选,[有四种:public\protected\默认\private],具体在后面说 √返回类型 1.一个方法最多有一 ...
- SpringBoot面试题的零碎整理
面试题1:简述一下Springboot相对SSM做了哪些提升? 首先,SpringBoot是采用"约定大于配置"(Convention over Configuration)的理念 ...
- 第119篇: JavaScript 类
好家伙,我们先来复习一下 关于Java,类的三大特征: 1.封装,也就是把客观事物封装成抽象的类,并且类可以把自己的数据和方法只让可信的类或者对象操作,对不可信的进行信息隐藏. 2.继承,继承性更 ...
- 深入解析ASP.NET Core MVC的模块化设计[下篇]
ASP.NET Core MVC的"模块化"设计使我们可以构成应用的基本单元Controller定义在任意的模块(程序集)中,并在运行时动态加载和卸载.<设计篇>介绍了 ...
- 单词本z custom cu = com 一起 都, st=suet 自己, om 尾缀, 都是自己身上的 = 习惯,习俗
单词本z custom cu = com 一起 都, st=suet 自己, om 尾缀, 都是自己身上的 = 习惯,习俗 custom 来自拉丁语 consuetus cu = com st = s ...
- StatefulSet是怎样实现的
StatefulSet是Kubernetes中用于管理有状态应用的标准实现.与Deployment不同,StatefulSet为每个Pod提供了一个唯一的.稳定的网络标识符,并且Pod的启动和停止顺序 ...
- Python使用pyecharts库构建股票交易 可交互可视化展示——基于Tushare大数据开放社区
Python使用pyecharts库构建股票交易 可交互可视化展示--基于Tushare大数据社区 1.前言 大家好!欢迎各位访问我的博客,今天给大家分享的是 python使用pyecharts库构建 ...
- stm32 boot0硬件接法导致的概率性启动失败问题总结和反思
概要 问题概要,板子在稳压电源上工作很好,可一旦接了电池,stm32就会出现概率性的无法启动.加上项目比较急,这个问题阻塞一直无法量产.真是非常的要命啊. 思路分析 既然是不同的电源会导致这个问题 ...