Cod sursa(job #1265756)

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

using namespace std;

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

struct fractie
{
    long long sus, jos;
}left[100009];

long long gcd (long long a, long long b)
{
    long long r;
    while (b)
    {
        r = a % b;
        a = b;
        b = r;
    }
    return a;
}

fractie simplifica (fractie x)
{
    long long C = gcd (x.sus, x.jos);
    x.sus /= C;
    x.jos /= C;
    return x;
}

fractie make_fractie (long long sus, long long jos)
{
    fractie ans;
    ans.sus = sus;
    ans.jos = jos;
    ans = simplifica (ans);
    return ans;
}

bool mai_mic_sau_egal(fractie a, fractie b)
{
    return ((long long) 1LL * a.sus * b.jos <= 1LL * b.sus * a.jos);
}

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

fractie x_inter (dreapta a, dreapta b)
{
    if (a.a == b.a) return make_fractie (-1000009, 1);
    return make_fractie( 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;
    /*if (j == 9)
    {
        for (int i=1; i<=n_stiva; i++)
            printf ("%lld %lld %lld/%lld\n", A[stiva[i]].a, A[stiva[i]].b, left[i].sus, left[i].jos);
    }*/
    ////caut functie cu maximul in X
    p = 1;
    u = n_stiva;
    while (p<=u)
    {
        mij = (p+u) >> 1;
        if (mai_mic_sau_egal (left[mij], make_fractie (X, 1)) )
        {
            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 && mai_mic_sau_egal ( 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] = make_fractie( -10000009 , 1);
    stiva[++n_stiva] = j;
}

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

return 0;
}