样例不过求条
查看原帖
样例不过求条
398152
MinimumSpanningTree最小生成树楼主2024/5/29 13:24
#include<iostream>
#include<cstdio>
using namespace std;
typedef long long ll;
const int N=1e6+100;
int n,a,b,c,l,r,q[N];
ll s[N],dp[N];
ll get_x(int x)
{
	return s[x];
}
ll get_y(int x)
{
	return dp[x]+a*s[x]*s[x]-b*s[x];
}
ll slope_fz(int x,int y)
{
	return get_y(x)-get_y(y);
}
ll slope_fm(int x,int y)
{
	return get_x(x)-get_x(y); 
}
int main()
{
	scanf("%d%d%d%d",&n,&a,&b,&c);
	for(int i=1;i<=n;i++) 
	{
		scanf("%lld",&s[i]);
		s[i]+=s[i-1];
	}
	for(int i=1;i<=n;i++)
	{
		while(l<r&&slope_fz(q[l],q[l+1])>2*a*s[i]*slope_fm(q[l],q[l+1])) l++;
		dp[i]=-((2*a*s[i])*get_x(q[l])-get_y(q[l])-a*s[i]*s[i]-b*s[i]-c);
		while(l<r&&slope_fz(q[r-1],q[r])*slope_fm(q[r],i)<=slope_fz(q[r],i)*slope_fm(q[r-1],q[r])) r--;
		q[++r]=i;
		//printf("%lld ",dp[i]);
	}
	printf("%lld",dp[n]);
	return 0;
}
/*
k=2a*sum[i]
x=sum[j]
b=dp[i]-a*sum[i]*sum[i]-b*s[i]-c
y=dp[j]+a*sum[j]*sum[j]-b*sum[j]
*/
2024/5/29 13:24
加载中...