Print Article
题目
解析
仍然还是恶心的斜率优化,直接上代码吧(内带注释)
code:
#include<cstdio>
#include<algorithm>
using namespace std;
inline bool idigit(char x){
return (x<'0'|x>'9')?0:1;}
inline int read()
{
int num=0,f=1;
char c=0;
while(!idigit(c=getchar())){
if(c=='-')f=-1;}
while(idigit(c))num=(num<<1)+(num<<3)+(c&15),c=getchar();
return num*f;
}
inline void write(int x)
{
int F[20];
int tmp=x>0?x:-x;
if(x<0)putchar('-');
int cnt=0;
while(tmp>0){
F[cnt++]=tmp%10+'0';tmp/=10;}
while(cnt>0)putchar(F[--cnt]);
if(x==0)putchar('0');
putchar('\n');
}//日常IO优化,fread就大可不必了
int n,m,a[500010],dp[500010],q[500010],l,r;//dp[i]为前i个的最优解
inline int D1(int x,int y){
return dp[x]+a[x]*a[x]-dp[y]-a[y]*a[y];}
inline int D2(int x,int y){
return a[x]-a[y];}
inline int Dp(int x,int y){
return dp[x]+m+(a[x]-a[y])*(a[x]-a[y]);}//用方便计算
inline void DP()
{
l=0,r=0;//队列初始化为一个0
for(int i=1;i<=n;++i)
{
while(l<r&&D1(q[l+1],q[l])<=2*a[i]*D2(q[l+1],q[l]))++l;//删左端
dp[i]=Dp(q[l],i);//计算价格
while(l<r&&D1(i,q[r])*D2(q[r],q[r-1])<=D2(i,q[r])*D1(q[r],q[r-1]))--r;//删右端
q[++r]=i;
}
write(dp[n]);
}
signed main()
{
while(scanf("%d",&n)!=EOF)
{
m=read(),dp[0]=a[0]=0;
for(int i=1;i<=n;++i)a[i]=read()+a[i-1],dp[i]=0;//读入
DP();
}
return 0;
}