BZOJ 1911 特别行动队

Posted on 2016-08-26 22:28  ziliuziliu  阅读(144)  评论(0编辑  收藏  举报

另一个版本的斜率优化。。。这个要好理解一些。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define maxn 1000050
using namespace std;
struct pnt
{
    long long x,y;
}p[maxn];
long long n,a,b,c,s[maxn],dp[maxn],q[maxn],l,r;
long long get_f(long long x,long long y)
{
    long long r=s[y]-s[x];
    return a*r*r+b*r+c;
}
long long get_x(long long x)
{
    return s[x];
}
long long get_y(long long x)
{
    return dp[x]+a*s[x]*s[x]-b*s[x];
}
double slop(long long a,long long b)
{
    return (double)(p[a].y-p[b].y)/(p[a].x-p[b].x);
}
int main()
{
    scanf("%lld",&n);
    scanf("%lld%lld%lld",&a,&b,&c);
    for (long long i=1;i<=n;i++)
    {
        scanf("%lld",&s[i]);s[i]+=s[i-1];
        long long k=2*a*s[i];
        while (l<r && p[q[l]].y-k*p[q[l]].x<p[q[l+1]].y-k*p[q[l+1]].x) l++;
        long long t=q[l];
        dp[i]=dp[t]+get_f(t,i);
        p[i].x=get_x(i);p[i].y=get_y(i);
        while (l<r && slop(q[r-1],q[r])<slop(q[r-1],i)) r--;
        q[++r]=i;
    }
    printf("%lld\n",dp[n]);
    return 0;
}