Cod sursa(job #2053664)

Utilizator alexpetrescuAlexandru Petrescu alexpetrescu Data 1 noiembrie 2017 02:41:36
Problema Euro Scor 100
Compilator cpp Status done
Runda Lista lui wefgef Marime 1.28 kb
#include <fstream>

std::ifstream fin("euro.in");
std::ofstream fout("euro.out");

#define MAXN 34567

int i;
long long d[MAXN + 1], s[MAXN + 1];
int dq[MAXN + 1];

inline double intersect(int a, int b) {
    return (d[a] - d[b]) /(double) (s[a] - s[b]);
}

inline bool ever(int a, int b) {
    if (s[a] == s[b]) return d[a] > d[b];
    else if (s[a] < s[b]) return 1;
    else return (d[a] > d[b] && intersect(a, b) >= i);
}

inline bool better(int a, int b, int c) {
    if (!ever(a, b)) return 0;
    else if (!ever(b, a)) return 1;
    else return intersect(a, c) <= intersect(b, c);
}

inline bool check(int a, int b) {
    if (s[a] == s[b]) return 0;
    else return intersect(a, b) <= i;
}

int main() {
    int n, t, st = 0, dr = 0;
    fin >> n >> t;

    for (i = 1; i <= n; i++) {
        fin >> s[i];
        s[i] += s[i - 1];

        while (st < dr - 1 && better(i - 1, dq[dr - 1], dq[dr - 2]))
            dr--;
        if (st == dr - 1 && !ever(dq[dr - 1], i - 1))
            dr--;
        if (st == dr || ever(i - 1, dq[dr - 1]))
            dq[dr++] = i - 1;
        while (st < dr - 1 && check(dq[st], dq[st + 1]))
            st++;

        d[i] = i * (s[i] - s[dq[st]]) + d[dq[st]] - t;
    }

    fout << d[n];

    return 0;
}