Cod sursa(job #585899)

Utilizator sealTudose Vlad seal Data 30 aprilie 2011 12:33:01
Problema Avioane Scor 100
Compilator cpp Status done
Runda Algoritmiada 2011, Runda Finală, Open Marime 1.8 kb
#include<cstdio>
#include<list>
#include<algorithm>
#include<vector>
#define INPUT "avioane.in"
#define OUTPUT "avioane.out"
#define MAXN 100001
#define ll long long
using namespace std;
int A[MAXN], n;
list<int> L;
bool Deleted[MAXN];
vector< pair<int, list<int>::iterator> > V[MAXN];

ll max(ll a, ll b)
{
    return a > b ? a : b;
}

void do_insert(list<int>::iterator it)
{
    if(it == L.begin())
        return;
    int j = *it;
    --it;
    int i = *it;
    int dif = A[j] - A[i];
    if(dif == 0)
        return;
    int p = ((ll)(j - i) * A[i] + dif - 1) / dif + j - 1;
    if(p < n)
        V[p].push_back(make_pair(j, ++it));
}

int main()
{
    int i, j, poz;
    ll ans, val;
    list<int>::iterator it, it2;

    freopen(INPUT, "r", stdin);
    freopen(OUTPUT, "w", stdout);

    scanf("%d", &n);
    for(i = 1; i <= n; ++i)
        scanf("%d", A + i);

    sort(A + 1, A + n + 1);

    if(n == 1)
    {
        printf("%d\n", A[1]);
        return 0;
    }

    L.push_back(1);
    ans = A[1] + A[2] * (n - 1);
    for(i = 2; i < n; ++i)
    {
        L.push_back(i);
        it = L.end(); --it;
        do_insert(it);
        for(j = 0; j < V[i].size(); ++j)
        {
            poz = V[i][j].first;
            if(Deleted[poz])
                continue;
            val = (ll)(i - poz + 1) * A[poz];
            it = V[i][j].second;
            while(it != L.begin())
            {
                it2 = --it; ++it;
                if(val >= (ll)(i - *it2 + 1) * A[*it2])
                {
                    Deleted[*it2] = 1;
                    L.erase(it2);
                }
                else
                    break;
            }
            do_insert(it);
        }
        ans = max(ans, (ll)(i - *L.begin() + 1) * A[*L.begin()] + (ll)A[i + 1] * (n - i));
    }

    printf("%lld\n", ans);

    return 0;
}