Pagini recente » Cod sursa (job #2782777) | Cod sursa (job #2286480) | Cod sursa (job #3242529) | Cod sursa (job #1324003) | Cod sursa (job #1265756)
#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;
}