WA80分求助,救救我,救救我。

P4655 [CEOI2017] Building Bridges

zasdcn @ 2022-09-24 07:00:07

#include<bits/stdc++.h>
#define int long long
const int N=2e5,VAL=2e6+10,inf=1e18;
typedef long long ll;
typedef long double db;
using namespace std;
int n,h[N],Cov[VAL<<2],w[N],f[N];
struct Line{ll k,b;}line[N];
ll K(int i){return -2*h[i];}
ll B(int i){return f[i]+h[i]*h[i]-w[i];}
ll calc(int id,int x){return line[id].k*x+line[id].b;}
struct Segment{
    #define lson p<<1
    #define rson p<<1|1    
    void upd(int p,int l,int r,int id){
        int mid=l+r>>1;
        if(calc(id,mid)<calc(Cov[p],mid))swap(Cov[p],id);
        if(calc(id,l)<calc(Cov[p],l))upd(lson,l,mid,id);
        if(calc(id,r)<calc(Cov[p],r))upd(rson,mid+1,r,id);
    }
    int query(int p,int l,int r,int x){
        if(l==r)return calc(Cov[p],x);
        int mid=l+r>>1,res=calc(Cov[p],x);
        if(x<=mid)return min(res,query(lson,l,mid,x));
        return min(res,query(rson,mid+1,r,x));
    }
}S;
signed main(){
    ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
    cin>>n;
    for(int i=1;i<=n;++i)cin>>h[i];
    for(int i=1;i<=n;++i)cin>>w[i];
    for(int i=1;i<=n;++i)w[i]+=w[i-1];
    f[1]=0;line[1]=Line{K(1),B(1)};S.upd(1,0,VAL,1);
    for(int i=2;i<=n;++i){
        f[i]=h[i]*h[i]+w[i-1]+S.query(1,0,VAL,h[i]);
        line[i]=Line{K(i),B(i)};S.upd(1,0,VAL,i);
    }
    cout<<f[n]<<"\n";
    return 0;
}

by zasdcn @ 2022-09-24 07:01:16

@zasdcn 用李超线段树写的


by Neutralized @ 2022-09-24 07:49:16

@zasdcn 李超树询问的时候当前节点存储的直线可能为空,若不在 query 里特判,最好把 line[0] 都设置为 (0,+ \infty)
加上之后就过了。


by zasdcn @ 2022-09-24 14:07:45

@Neutralized 谢谢大佬


|