Cod sursa(job #2445493)

Utilizator caesar2001Stoica Alexandru caesar2001 Data 4 august 2019 12:23:22
Problema Avioane Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 1.5 kb
#include <bits/stdc++.h>

using namespace std;

ifstream in("avioane.in");
ofstream out("avioane.out");

typedef long long ll;

struct Line {
    ll a, b;

    bool operator< (const Line &other) const {
        if(a == other.a)
            return b < other.b;
        return a < other.a;
    }
};

int isbad(const Line &x, const Line &y, const Line &z) {
    return (y.b - x.b) * (y.a - z.a) >= (z.b - y.b) * (x.a - y.a);
}

ll getY(const Line &l, ll x) {
    return l.a * x + l.b;
}

void rundp(int n, const vector<Line> &lines, vector<ll> &dp) {
    vector<int> stk(n + 1, 0);
    int l = 1, r = 0;

    for(int i = 1; i <= n; i ++) {
        while(r - l + 1 >= 2 && isbad(lines[stk[r - 1]], lines[stk[r]], lines[i]))
            r --;
        stk[++ r] = i;
        while(r - l + 1 >= 2 && getY(lines[stk[l]], i) < getY(lines[stk[l + 1]], i))
            l ++;

        dp[i] = getY(lines[stk[l]], i);
    }
}

int main() {

    int n;
    in >> n;
    vector<ll> v(n + 1);
    for(int i = 1; i <= n; i ++)
        in >> v[i];
    sort(v.begin() + 1, v.end());

    vector<vector<ll>> dp(2, vector<ll> (n + 1, 0));
    vector<Line> lines(n + 1);

    for(int i = 1; i <= n; i ++)
        lines[i] = {v[i], v[i] * (1 - i)};
    rundp(n, lines, dp[0]);
    for(int i = 1; i <= n; i ++)
        lines[i].b += dp[0][i - 1];
    rundp(n, lines, dp[1]);

    ll ans = 0;
    for(int i = 1; i <= n; i ++)
        ans = max(dp[1][i], ans);
    out << ans;

    return 0;
}