题目


分析

列出方程即为\(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的更多相关文章

  1. 洛谷.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_ ...

  2. 【BZOJ3672】【NOI2014】购票(线段树,斜率优化,动态规划)

    [BZOJ3672][NOI2014]购票(线段树,斜率优化,动态规划) 题解 首先考虑\(dp\)的方程,设\(f[i]\)表示\(i\)的最优值 很明显的转移\(f[i]=min(f[j]+(de ...

  3. BZOJ_3963_[WF2011]MachineWorks_斜率优化+CDQ分治

    BZOJ_3963_[WF2011]MachineWorks_斜率优化+CDQ分治 Description 你是任意性复杂机器公司(Arbitrarily Complex Machines, ACM) ...

  4. 「线段树」「单点修改」洛谷P1198 [JSOI2008]最大数

    「线段树」「单点修改」洛谷P1198 [JSOI2008]最大数 题面描述 现在请求你维护一个数列,要求提供以下两种操作: 1. 查询操作. 语法:Q L 功能:查询当前数列中末尾L个数中的最大的数, ...

  5. [Noi2014]购票 BZOJ3672 点分治+斜率优化+CDQ分治

    Description  今年夏天,NOI在SZ市迎来了她30周岁的生日.来自全国 n 个城市的OIer们都会从各地出发,到SZ市参加这次盛会.全国的城市构成了一棵以SZ市为根的有根树,每个城市与它的 ...

  6. 【BZOJ-1492】货币兑换Cash DP + 斜率优化 + CDQ分治

    1492: [NOI2007]货币兑换Cash Time Limit: 5 Sec  Memory Limit: 64 MBSubmit: 3396  Solved: 1434[Submit][Sta ...

  7. BZOJ3963 WF2011MachineWorks(动态规划+斜率优化+cdq分治)

    按卖出时间排序后,设f[i]为买下第i台机器后的当前最大收益,则显然有f[i]=max{f[j]+gj*(di-dj-1)+rj-pi},且若此值<0,应设为-inf以表示无法购买第i台机器. ...

  8. bzoj1492/luogu4027 货币兑换 (斜率优化+cdq分治)

    设f[i]是第i天能获得的最大钱数,那么 f[i]=max{在第j天用f[j]的钱买,然后在第i天卖得到的钱,f[i-1]} 然后解一解方程什么的,设$x[j]=\frac{F[j]}{A[j]*Ra ...

  9. [BZOJ1492][NOI2007]货币兑换Cash(斜率优化+CDQ分治)

    1492: [NOI2007]货币兑换Cash Time Limit: 5 Sec  Memory Limit: 64 MBSubmit: 5838  Solved: 2345[Submit][Sta ...

  10. 【BZOJ2726】[SDOI2012]任务安排 斜率优化+cdq分治

    [BZOJ2726][SDOI2012]任务安排 Description 机器上有N个需要处理的任务,它们构成了一个序列.这些任务被标号为1到N,因此序列的排列为1,2,3...N.这N个任务被分成若 ...

随机推荐

  1. JAVA 考试管理系统 大作业(一):需求分析

    好家伙,有需要的拿去借鉴吧(虽然我也百度了很多) 题目如下: 题目四:考试管理系统 (选做要求:使用图形用户界面) 分3种用户角色:教务员(具有管理权限).教师.学生 l  教务员:可以进行用户管理( ...

  2. 图数据库|Nebula Graph v3.1.0 性能报告

    本文首发于 Nebula Graph Community 公众号 本文系 Nebula Graph 发行版 v3.1.0 的性能测试报告. 本文目录 测试环境 测试数据 关于 LDBC-SNB 测试说 ...

  3. cpu过高什么原因?怎么排查?

    运行大型程序或应用程序:当计算机运行大型程序或应用程序时,CPU需要处理更多的数据和指令,因此CPU占用率会相应地增加. 病毒或恶意软件:某些病毒或恶意软件会占用计算机的CPU资源来执行恶意任务,例如 ...

  4. RocketMQ(4) 消息的消费

    消费者从Broker中获取消息的方式有两种:pull拉取方式和push推动方式.消费者组对于消息消费的模 式又分为两种:集群消费Clustering和广播消费Broadcasting. 1. 获取消息 ...

  5. C++ //list容器 构造函数 //list赋值和交换 //list容器大小操作 //list插入和删除,移除 //清空 //list数据存取back(); front() //list 反转和排序

    1 //list容器 构造函数 //list赋值和交换 //list容器大小操作 2 //list插入和删除,移除 //清空 //list数据存取back(); front() 3 //list 反转 ...

  6. PostgreSql一个月学习计划

    1.背景 国内使用数据库最多的莫过于mysql,大部分程序员第一次接触数据库就是mysql.(毕竟免费的 = =!)但近年来,有一些黑马出现(如下图),其中表现最突出的莫过于PostgreSQL.特规 ...

  7. 一文搞懂Vue的MVVM模式与双向绑定

    v-model 是 Vue.js 框架中用于实现双向数据绑定的指令.它充分体现了 MVVM(Model-View-ViewModel)模式中的双向数据绑定特性.下面我们将详细解释 v-model 如何 ...

  8. [VueJsDev] 基础知识 - 常见编码集

    [VueJsDev] 目录列表 https://www.cnblogs.com/pengchenggang/p/17037320.html 常用编码集 ::: details 目录 目录 常用编码集 ...

  9. SQL语句之索引操作

    目录 索引 创建索引 CREATE INDEX 语句 CREATE UNIQUE INDEX 语句 索引多个列 删除索引 参考资料 索引 可以在表中创建索引,以便更加快速高效地查询数据. 用户无法看到 ...

  10. 解决linux平台无法使用getch()的问题

    参考https://www.cnblogs.com/jiangxinnju/p/5516906.html#:~:text=%E5%8F%A6%E5%A4%96%E5%A4%A7%E5%AE%B6%E5 ...