斜率优化DP
第一次写 凸包什么的太容易错了
还有这个题有问题...会爆long long啊 做数据的注意了吗??
#include <cmath>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
struct H
{
long long x,y;
};
const int MAXN = 5e5+10;
long long n,m;
H team[MAXN];long long head,tail;
long long num[MAXN],s[MAXN],ans[MAXN];
bool can(H a,H b,H c)
{
long long x1=a.x-b.x;
long long y1=a.y-b.y;
long long x2=b.x-c.x;
long long y2=b.y-c.y;
return y1*x2-x1*y2<=0;
}
long long f(long long x,long long k)
{
return team[x].y-k*team[x].x;
}
void work()
{
for(long long i=1;i<=n;i++) scanf("%lld",&num[i]),s[i]=s[i-1]+num[i];
head=0;
tail=0;
for(long long i=1;i<=n;i++)
{
// for(long long j=head;j<=tail;j++) cout<<team[j].x<<' '<<team[j].y<<endl;
// cout<<' '<<endl;
// cout<<f(head,2*s[i])<<' '<<f(head+1,2*s[i])<<endl;
// long long mmin=1e9;
// for(long long j=head;j<=tail;j++) mmin=min(mmin, f(j,2*s[i]));
while(head<tail && f(head,2*s[i])>=f(head+1,2*s[i])) head++;//if((long long )s[i]*s[i]>2e9) cout<<(long long)s[i]*s[i]<<endl;
ans[i]=f(head,2*s[i])+m+s[i]*s[i];
// cout<<ans[i]<<endl;
H tmp=(H){s[i],s[i]*s[i]+ans[i]};
while (tail-head>0 && can(tmp,team[tail],team[tail-1])==true ) tail--;
team[++tail]=tmp;
}
printf("%lld\n",ans[n]);//cout<<s[n]<<endl;
}
int main()
{
// freopen("a.in","r",stdin);
// freopen("a.out","w",stdout);
while(scanf("%lld %lld",&n,&m)==2)
work();
return 0;
}