Cod sursa(job #585605)

Utilizator mugurelionutMugurel-Ionut Andreica mugurelionut Data 30 aprilie 2011 10:09:36
Problema Avioane Scor 100
Compilator cpp Status done
Runda Algoritmiada 2011, Runda Finală, Open Marime 2.27 kb
#include <stdio.h>
#include <vector>
#include <algorithm>

using namespace std;

#define NMAX 100100

vector<long long> v;
long long a[NMAX], b[NMAX], s, icross;
int dqidx[NMAX], dqifirst[NMAX];
int i, ifirst, j, k, x, N, li, ls;

int main() {
    // Read the input data.
    freopen("avioane.in", "r", stdin);
    scanf("%d", &N);

    for (i = 1; i <= N; i++) {
        scanf("%d", &x);
        v.push_back((long long) x);
    }

    sort(v.begin(), v.end());

    // Compute a[i].
    li = 0;
    ls = -1;

    a[0] = 0;
    for (i = 1; i <= N; i++) {
        a[i] = 0;

        // Clean-up the front of the deque.
        while (li < ls && dqifirst[li + 1] <= i)
            li++;

        // Clean-up the end of the deque.
        ifirst = i;
        while (li <= ls) {
            if (v[dqidx[ls] - 1] == v[i - 1]) {
                ifirst = N + 1;
                break;
            }

            if ((v[dqidx[ls] - 1] * (long long) (i - dqidx[ls] + 1)) - v[i - 1] < 0)
                icross = i;
            else
                icross = (long long) i + ((v[dqidx[ls] - 1] * (long long) (i - dqidx[ls] + 1)) - v[i - 1]) / (v[i - 1] - v[dqidx[ls] - 1]);

            if (icross < i) {
                icross = i;
            } else {
                if (v[dqidx[ls] - 1] * (long long) (icross - dqidx[ls] + 1) - v[i - 1] * (icross - i + 1) > 0)
                    icross++;
            }

            if (icross <= dqifirst[ls]) {
                ls--;
            } else {
                ifirst = icross;
                break;
            }
        }

        // Add the new line to the deque.
        ls++;
        dqidx[ls] = i;
        dqifirst[ls] = ifirst;

        s = v[dqidx[li] - 1] * (long long) (i - dqidx[li] + 1);
        if (s > a[i])
            a[i] = s;
    }

    // Compute b[i].
    b[N + 1] = 0;
    for (i = N; i >= 1; i--) {
        b[i] = b[i + 1];
        s = v[i - 1] * (long long) (N - i + 1);
        if (s > b[i])
            b[i] = s;
    }

    // Compute the best sum.
    s = 0;
    for (i = 0; i <= N; i++)
        if (a[i] + b[i + 1] > s)
            s = a[i] + b[i + 1];

    // Print the result.
    freopen("avioane.out", "w", stdout);
    printf("%lld\n", s);

    return 0;
}