动态开点李超线段树求助25pts
查看原帖
动态开点李超线段树求助25pts
285617
黑影洞人楼主2022/8/30 23:09
#include<cstdio>
#include<algorithm>
#define lc lson[p]
#define rc rson[p]
#define inf 2147483647
#define N 1919810
using namespace std;
int dp[N];
struct Li_Chao_Segement_Tree{
	int tot,cnt=1,k[N],b[N],s[N],lson[N],rson[N],rt=1;
	int y(int x,int id){return x*k[id]+b[id];}
	void update(int &p,int l,int r,int k){
		if(!p)p=++cnt;
		if(l==r){
			if(y(l,k)<y(l,s[p]))s[p]=k;
			return;
		}
		int mid=(l+r)/2;
		if(y(mid,k)<y(mid,s[p]))swap(k,s[p]);
		if(y(l,k)<y(l,s[p]))update(lc,l,mid,k);
		else if(y(r,k)<y(r,s[p]))update(rc,mid+1,r,k);
	}
	void insert(int ki,int bi){
		k[++tot]=ki,b[tot]=bi;
		update(rt,0,N,tot);
	}
	int get(int p,int l,int r,int x){
		if(!p)return inf;
		if(l==r&&l==x)return y(l,s[p]);
		int mid=(l+r)/2;
		return min(x<=mid?get(lc,l,mid,x):get(rc,mid+1,r,x),y(x,s[p]));
	}
}lic;
int n,h[N],s[N];
signed main(){
	scanf("%d",&n);lic.b[0]=inf;
	for(int i=1;i<=n;i++)scanf("%d",&h[i]);
	for(int i=1;i<=n;i++)scanf("%d",&s[i]),s[i]+=s[i-1];
	lic.insert(-2*h[1],h[1]*h[1]-s[1]);
	for(int i=2;i<=n;i++){
		dp[i]=h[i]*h[i]+s[i-1]+lic.get(lic.rt,0,N,h[i]);
		lic.insert(-2*h[i],dp[i]+h[i]*h[i]-s[i]);
	}
	printf("%d",dp[n]);
	return 0;
}



2022/8/30 23:09
加载中...