ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

[CEOI2017]Building Bridges 题解

2021-11-06 21:31:49  阅读:192  来源: 互联网

标签:Building rt ch Bridges 题解 mid 斜率 calc


Statement

[P4655 CEOI2017]Building Bridges - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)

Solution

斜率优化DP+李超线段树

考虑设 \(f[i]\) 表示链接到 \(i\) 的最小代价,那么有:

\[f[i]=\min_{j<i}\{f[j]+(h_i-h_j)^2+sw[i-1]-sw[j]\} \]

这个是 \(O(n^2)\) 的,需要优化

看到这个平方项,充满了斜率优化的味道,我们考虑移项

\[f[i]=h_i^2+sw[i-1]+\min_{j<i}\{-2h_ih_j+h_j^2+f[j]-sw[j]\} \]

我们可以看作一条斜率为 \(-2h_j\) ,截距为 \(h_j^2+f[j]-sw[j]\) 的直线

我们考虑用李超线段树维护这些直线,对于一个 \(i\) ,只需要求出当 \(x=h_i\) 时最小值就可以了

这样就是 \(O(n\log n)\)

Code

#include<bits/stdc++.h>
#define int long long
#define ls rt<<1
#define rs rt<<1|1
using namespace std;
const int N = 1e5+5;
const int M = 1e6+5;

int read(){
    int s=0,w=1;char ch=getchar();
    while(ch<'0'||ch>'9'){if(ch=='-')w=-1;ch=getchar();}
    while(ch>='0'&&ch<='9')s=s*10+ch-'0',ch=getchar();
    return s*w;
}

struct Line{int k,b;}line[N];
int t[M<<2],h[N],w[N],sw[N],f[N];
int n;

int calc(int x,int id){return x*line[id].k+line[id].b;}
void insert(int l,int r,int rt,int u){
    if(l==r)return (calc(l,t[rt])>calc(l,u)&&(t[rt]=u,1)),void();//
    int mid=(l+r)>>1;
    if(calc(mid,t[rt])>calc(mid,u))swap(t[rt],u);//
    if(calc(l,u)<calc(l,t[rt]))insert(l,mid,ls,u);//
    else if(calc(r,u)<calc(r,t[rt]))insert(mid+1,r,rs,u);//
}
int query(int l,int r,int rt,int u){//
    if(l==r)return calc(l,t[rt]);
    int mid=(l+r)>>1,tmp=calc(u,t[rt]);
    if(u<=mid)return min(tmp,query(l,mid,ls,u));
    else return min(tmp,query(mid+1,r,rs,u));
}

signed main(){
    n=read(),line[0]={0,(int)1e18};
    for(int i=1;i<=n;++i)h[i]=read();
    for(int i=1;i<=n;++i)w[i]=read(),sw[i]=sw[i-1]+w[i];
    line[1]={-2*h[1],h[1]*h[1]-sw[1]},insert(0,M,1,1);
    for(int i=2;i<=n;++i){
        f[i]=query(0,M,1,h[i])+h[i]*h[i]+sw[i-1];
        line[i]={-2*h[i],h[i]*h[i]+f[i]-sw[i]},insert(0,M,1,i);
    }
    printf("%lld\n",f[n]);
    return 0;
}

标签:Building,rt,ch,Bridges,题解,mid,斜率,calc
来源: https://www.cnblogs.com/wyb-sen/p/15518512.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有