Cod sursa(job #1957925)

Utilizator bciobanuBogdan Ciobanu bciobanu Data 7 aprilie 2017 21:02:10
Problema Euro Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.44 kb
#include <bits/stdc++.h>

using namespace std;

const int kMaxN = 34567 + 1;

struct Line {
    long long a, b;

    Line(const long long _a = 0LL, const long long _b = 0LL) : a(_a), b(_b) {
    }

    long long get(int x) const {
        return a * x + b;
    }
} T[4 * kMaxN];

void update(int node, int lo, int hi, Line x) {
    if(T[node].get(hi) >= x.get(hi))
        return;

    int mid = (lo + hi) / 2;

    if(T[node].get(mid) < x.get(mid) || (T[node].get(mid) == x.get(mid) && T[node].get(lo) < x.get(lo))) {
        T[node] = x;

        if(lo != hi)
            update(2 * node, lo, mid, x);
    } else if(lo != hi) {
        update(2 * node + 1, mid + 1, hi, x);
    }
}

long long query(int node, int lo, int hi, int pos) {
    if(lo == hi)
        return T[node].get(pos);

    int mid = (lo + hi) >> 1;
    if(pos <= mid)
        return max(T[node].get(pos), query(2 * node, lo, mid, pos));
    else
        return max(T[node].get(pos), query(2 * node + 1, mid + 1, hi, pos));
}

long long SP[kMaxN], DP[kMaxN];

int main() {
    freopen("euro.in", "r", stdin);
    freopen("euro.out", "w", stdout);

    int n, t;
    scanf("%d%d", &n, &t);
    for(int i = 1; i <= n; ++i) {
        int x;
        scanf("%d", &x);
        SP[i] = SP[i - 1] + x;
        DP[i] = SP[i] * i + query(1, 1, n, i) - t;
        update(1, 1, n, Line(-SP[i], DP[i]));
    }
    printf("%lld\n", DP[n]);
    return 0;
}