Cod sursa(job #23067)

Utilizator dominoMircea Pasoi domino Data 27 februarie 2007 23:30:52
Problema Euro Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.14 kb
#include <stdio.h>

#define FIN "euro.in"
#define FOUT "euro.out"
#define MAX_N 35000
#define ll long long
#define calc(i, j) (A[j] + (ll)(S[i]-S[j])*D[i] - T) // j < i
#define better(i, j, k) (calc(i, j) >= calc(i, k)) // j, k < i
#define useless(i, j, k) ((A[i]-A[j])*(S[j]-S[k]) >= (A[j]-A[k])*(S[i]-S[j])) // i < j < k

int N, T, n, S[MAX_N], D[MAX_N], Q[MAX_N], ql, qr;
ll A[MAX_N];

int main(void)
{
    int i, x, sum = 0;

    freopen(FIN, "r", stdin);
    freopen(FOUT, "w", stdout);
    
    scanf("%d %d", &N, &T);
    for (n = 0, i = 1; i <= N; i++)
    {
        scanf("%d", &x);
        if ((sum += x) < 0)
        {
            S[n+1] = S[n]+sum; 
            D[++n] = i;
            sum = 0;
        }
    }
    if (D[n] != N)
       S[n+1] = S[n]+sum, D[++n] = N;

    fprintf(stderr, "%d %d %d\n", n, S[n], D[n]);

    Q[ql = qr = 0] = 0;
    for (i = 1; i <= n; i++)
    {
        for (; ql < qr && better(i, Q[ql+1], Q[ql]); ql++);
        A[i] = calc(i, Q[ql]);
        for (; ql < qr && useless(Q[qr-1], Q[qr], i); qr--);
        Q[++qr] = i;
    }

    printf("%lld\n", A[n]);

    return 0;
}