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]
都设置为
加上之后就过了。
by zasdcn @ 2022-09-24 14:07:45
@Neutralized 谢谢大佬