博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

[HYSBZ][1010][玩具装箱toy]

Posted on 2012-05-12 18:12  紫华弦筝  阅读(193)  评论(0编辑  收藏  举报

题目:http://acm.hust.edu.cn:8080/judge/problem/viewProblem.action?id=16331

View Code
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <algorithm>

#define ll long long
#define clr(a,b) memset(a, b, sizeof(a))
using namespace std;

const int N = 50000+10;
const int M = 10000+10;
const int inf = 0x3f3f3f3f;

ll n, m, l, r;
ll a[N], dp[N], q[N];

ll sqr(ll a){return a*a;}

void input()
{
    a[0] = dp[0] = 0;
    for (int i=1; i<=n; i++)
        scanf("%d", &a[i]), a[i]+=a[i-1];
}

ll dy(ll k1, ll k2)
{
    return dp[k1]-dp[k2]+sqr(k1+a[k1]+m+1)-sqr(k2+a[k2]+m+1);
}

ll dx(ll k1, ll k2)
{
    return k1+a[k1]-k2-a[k2];
}

int main()
{
    //freopen("D:/a.txt", "r", stdin);
    while (~scanf("%lld%lld", &n, &m))
    {
        input();
        q[l=r=0] = 0;
        for (int i=1; i<=n; i++)
        {
            while (l<r && dy(q[l],q[l+1])>=2*(i+a[i])*dx(q[l],q[l+1]))l++;
            dp[i] = dp[q[l]] + sqr(i-q[l]-1+a[i]-a[q[l]]-m);
            while (l<r && dy(q[r-1],q[r])*dx(q[r],i)>=dy(q[r],i)*dx(q[r-1],q[r]))r--;
            q[++r]=i;
        }
        printf("%lld\n", dp[n]);
    }
    return 0;
}