CDQ分治 85pts 求助
查看原帖
CDQ分治 85pts 求助
480015
是WXD楼主2022/10/24 11:11

rt,开了全局 ll 还是 85pts(WA#10 #16 #17)。

#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <algorithm>
#define ll long long
using namespace std;
int n;
ll f[100005];
ll h[100005];
ll sum[100005];

inline ll re(){
	ll k=0,f=1;
	char cre=getchar();
	while(!('0'<=cre&&cre<='9')){
		if(cre=='-') f=-1;
		cre=getchar();
	}
	while('0'<=cre&&cre<='9'){
		k=k*10+(cre^48);
		cre=getchar();
	}
	return 1ll*k*f;
}

void wr(ll x){
	if(x<0){
		putchar('-');
		x=~x+1;
	}
	if(x>9) wr(x/10);
	putchar(x%10^48);
}

struct node{		//决策点 
	int id;
	ll x,y;
}a[100005],cpy[100005];
int q[100005],head,tail;

inline bool cmp(node a,node b){
	return a.x^b.x?a.x<b.x:a.y<b.y;
}

inline ll Y(int i){
	return f[i]-sum[i]+h[i]*h[i];
}

void CDQ(int l,int r){
	if(l==r){
		a[l].y=Y(l);
		return;
	}
	int mid=(l+r)>>1;
	int x=l,y=mid+1;
	for(int i=l;i<=r;++i){
		if(a[i].id<=mid) cpy[x++]=a[i];
		else cpy[y++]=a[i];
	}
	for(int i=l;i<=r;++i) a[i]=cpy[i];
	CDQ(l,mid);		//处理左部分 
	head=1,tail=0;
	for(int i=l;i<=mid;++i){		//左边维护凸包 
		if(i>l&&a[i].x==a[i-1].x) continue;
		while(head<tail&&(a[i].y-a[q[tail]].y)*(a[q[tail]].x-a[q[tail-1]].x)<=(a[q[tail]].y-a[q[tail-1]].y)*(a[i].x-a[q[tail]].x)) --tail;
		q[++tail]=i;
	}
	for(int i=mid+1;i<=r;++i){		//更新右部分答案 
		while(head<tail&&(a[q[head+1]].y-a[q[head]].y)<=2*a[i].x*(a[q[head+1]].x-a[q[head]].x)) ++head;
		int u=a[i].id,v=a[q[head]].id;
		f[u]=min(f[u],f[v]+sum[u-1]-sum[v]+(h[u]-h[v])*(h[u]-h[v]));
	}
	CDQ(mid+1,r);	//处理右部分
	x=l,y=mid+1;
	int cnt=l;
	while(x<=mid&&y<=r){		//合并答案 
		if(a[x].x<a[y].x||(a[x].x==a[y].x&&a[x].y<a[y].y)) cpy[cnt++]=a[x++];
		else cpy[cnt++]=a[y++];
	}
	while(x<=mid) cpy[cnt++]=a[x++];
	while(y<=r) cpy[cnt++]=a[y++];
	for(int i=l;i<=r;++i) a[i]=cpy[i];
}

signed main(){
	n=re();
	for(int i=1;i<=n;++i){
		h[i]=re();
		a[i].id=i;
		a[i].x=h[i];
	}
	for(int i=1;i<=n;++i){
		sum[i]=re();
		sum[i]+=sum[i-1];
	}
	for(int i=2;i<=n;++i) f[i]=0x3f3f3f3f;
	sort(a+1,a+1+n,cmp);
	CDQ(1,n);
	wr(f[n]);
	return 0;
}
2022/10/24 11:11
加载中...