Cod sursa(job #1957838)

Utilizator bciobanuBogdan Ciobanu bciobanu Data 7 aprilie 2017 20:04:00
Problema Euro Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.57 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(lo > hi || (T[node].get(lo) >= x.get(lo) && T[node].get(hi) >= x.get(hi)))
        return;

    if(T[node].get(lo) < x.get(lo) && T[node].get(hi) < x.get(hi)) {
        T[node] = x;
        return;
    }

    int mid = (lo + hi) / 2;
    if(T[node].get(lo) < x.get(lo)) {
        swap(T[node], x);
    }

    if(T[node].get(mid) > x.get(mid)) {
        update(2 * node + 1, mid + 1, hi, x);
    } else {
        swap(T[node], x);
        update(2 * node, lo, mid, 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;
}