Cod sursa(job #1265744)

Utilizator geniucosOncescu Costin geniucos Data 17 noiembrie 2014 18:24:43
Problema Avioane Scor 50
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.55 kb
#include<cstdio>
#include<algorithm>

using namespace std;

long long N, n_stiva, stiva[100009], a[100009];
double left[100009];
long long maxi;

struct dreapta
{
    long long a, b;
}A[100009];

double x_inter (dreapta a, dreapta b)
{
    if (a.a == b.a) return -1000000009.0;
    return (double) (b.b - a.b) / (a.a - b.a);
}

int main()
{
freopen ("avioane.in", "r", stdin);
freopen ("avioane.out", "w", stdout);
scanf ("%lld", &N);
for (int i=1; i<=N; i++)
    scanf ("%lld", &a[i]);
sort (a+1, a+N+1);

for (int j=1; j<=N; j++)
{
    //////////////////////////////////////////////////////////////////////updatez rezultatul
    int X = j, p, u, mij, ras = 0;
    long long curr_val;

    ////caut functie cu maximul in X
    p = 1;
    u = n_stiva;
    while (p<=u)
    {
        mij = (p+u) >> 1;
        if (left[mij] <= X)
        {
            ras = mij;
            p = mij + 1;
        }
        else u = mij - 1;
    }

    curr_val = 1LL * a[j] * (N+1-j);
    if (ras == 0) ;
    else curr_val += 1LL * X * A[stiva[ras]].a + A[stiva[ras]].b;
    if (curr_val > maxi)
        maxi = curr_val;
    //////////////////////////////////////////////////////////////////////updatez multimea functiilor
    A[j].a = a[j];
    A[j].b = -1LL * a[j] * j;
    while (n_stiva && x_inter (A[j], A[stiva[n_stiva]]) <= left[n_stiva])
        n_stiva --;

    if (n_stiva) left[n_stiva + 1] = x_inter (A[j], A[stiva[n_stiva]]);
    else left[1] = -1000000009.0;
    stiva[++n_stiva] = j;
}

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

return 0;
}