Cod sursa(job #1534314)

Utilizator bogdan10bosBogdan Sitaru bogdan10bos Data 23 noiembrie 2015 17:34:29
Problema Avioane Scor 70
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.36 kb
#include <bits/stdc++.h>

#define INF (1 << 30)
#define LLINF (1LL << 62)
#define mod 666013

using namespace std;

typedef long long LL;

class Reader
{
private:
    char buff[100805];
    int buffer, cnt;

public:
    Reader()
    {
        buffer = 1 << 15;
        cnt = buffer - 1;
    }

    char gChar()
    {
        if(++cnt == buffer)
        {
            cnt = 0;
            fread(buff, buffer, 1, stdin);
        }
        return buff[cnt];
    }

    int gInt()
    {
        int nr = 0;
        char ch = gChar();
        while(ch < '0' || '9' < ch)
            ch = gChar();
        while('0' <= ch && ch <= '9')
        {
            nr = nr * 10 + ch - '0';
            ch = gChar();
        }
        return nr;
    }
};
Reader rdr;

struct dreapta
{
    int vit, start, lft;
} drp, dr[100005], r[100005];

int n, i, k, pct;
LL sol, mx;
int v[100005];

stack <dreapta> stv;

int intersect(dreapta a, dreapta b)
{
    if(a.vit == b.vit)
        return -1;

    int rez = (b.start - a.start) / (a.vit - b.vit);
    if( rez * (a.vit - b.vit) < (b.start - a.start) )
        rez++;
    return rez;
}

bool cmp(dreapta a, dreapta b)
{
    if(a.vit == b.vit)
        return a.start < b.start;
    return a.vit < b.vit;
}

int main()
{
    freopen("avioane.in", "r", stdin);
    freopen("avioane.out", "w", stdout);

    n = rdr.gInt();
    for(i = 1; i <= n; i++)
        v[i] = rdr.gInt();

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

    for(i = 1; i <= n; i++)
    {
        dr[i].vit = v[i];
        dr[i].start = -v[i] * i;
    }

    sort(dr + 1, dr + n + 1, cmp);

    for(i = 1; i <= n; i++)
    {
        while(!stv.empty())
        {
            pct = intersect(dr[i], stv.top());
            if(pct <= stv.top().lft)
                stv.pop();
            else
                break;
        }

        drp = dr[i];
        if(stv.empty())
            drp.lft = 0;
        else
            drp.lft = pct;
        stv.push(drp);
    }

    while(!stv.empty())
    {
        r[++k] = stv.top();
        stv.pop();
    }

    for(i = 2; i <= n; i++)
    {
        while(k > 1 && i >= r[k - 1].lft)
            k--;

        sol = 1LL * v[i] * (n - i + 1) + 1LL * r[k].start + 1LL * r[k].vit * i;
        mx = max(sol, mx);
    }

    printf("%lld", mx);

    return 0;
}