Pagini recente » Cod sursa (job #229263) | Cod sursa (job #3188746) | Cod sursa (job #1376495) | Cod sursa (job #2613502) | Cod sursa (job #1165799)
#include <iostream>
#include <fstream>
#include <algorithm>
using namespace std;
const int NMax = 100010;
const long long INF = 4000000000000000000LL;
int N;
int v[NMax];
long long ans;
int d[NMax];
void Read()
{
ifstream f("avioane.in");
f >> N;
int newN = 0;
for (int i = 1; i <= N; ++ i)
{
int x; f >> x;
if (x > 0)
v[++newN] = x;
}
N = newN;
f.close();
}
long long Better(const int i, const int j)
{
/// returneaza numarul minim de zile dupa care faptul de a lua ca pret de bilet de economy al j-lea pret
/// este mai bine decat al lua pe al i-lea;
if (v[i] == v[j])
return INF;
if (1LL * v[i] * (j - i + 1) < 1LL * v[j])
return -INF;
return ((1LL * v[i] * (j - i + 1) - v[j]) / (v[j] - v[i])) + ((abs(1LL * v[i] * (j - i + 1) - v[j]) % (v[j] - v[i])) ? 1LL : 0LL);
}
inline long long Cost(const int i, const int j)
{
/// returneaza costul total daca as alege ca pret de economy pretul i si ca pret de business pretul j
return 1LL * v[j] * (N - j + 1) + 1LL * v[i] * (j - i);
}
void Solve()
{
sort (v + 1, v + N + 1);
ans = max(ans, Cost(1, 2));
int st, dr;
st = dr = 1;
d[1] = 1;
for (int i = 3; i <= N; ++ i)
{
ans = max(ans, Cost(d[st], i));
while ((st < dr && 1LL * d[st+1] + Better(d[st], d[st+1]) <= 1LL * i - 1LL))
{
/// scot acolo bilete din varful deque-ului care nu mai sunt bune fata de cele din dreapta
/// adica daca d[st+1] ar fi biletul de economy si mi-ar face pana la ziua i - 1 (inclusiv)
/// un cost mai bun (sau egal) cu costul pe care il face d[st] pana la a ziua i - 1(inclusiv)
/// atunci scot d[st]
++ st;
ans = max(ans, Cost(d[st], i));
}
if (st > dr)
d[++dr] = i - 1;
else if (v[i - 1] != v[d[dr]])
{
/// if este ca nu are sens sa iau in considerare un pret de economy pe pozitia i - 1 pentru ca
/// clar costul este mai bun pentru cel de pe pozitia dr cu dr < i - 1 pentru ca are mai multe zile pe care
/// le acopera. deci nu bag deloc in deque pe i - 1;
while ((dr > st && d[dr] + Better(d[dr], i - 1) <= d[dr - 1] + Better(d[dr - 1], d[dr])) || (dr == st && Better(d[dr], i - 1) + 1LL * (i - 1) < 1LL * (i - 1)))
{
/// daca timpul in care se face i - 1 mai bun fata de d[dr] este mai mic decat timpul in care
/// se face d[dr] mai bun decat d[dr - 1] atunci ii clar ca i - 1 o sa fie mai bun ca d[dr]
/// atunci ii clar ca d[dr] nu va fi niciodata bun si deci il elimin
--dr;
}
d[++dr] = i - 1;
}
if (st <= dr)
ans = max(ans, Cost(d[st], i));
}
}
void Write()
{
ofstream g("avioane.out");
g << ans << "\n";
g.close();
}
int main()
{
Read();
Solve();
Write();
return 0;
}