#include <bits/stdc++.h>
using namespace std;
template <class T>
void debug(T a, T b) {
  ;
}
template <class T>
void chmin(T& a, const T& b) {
  if (a > b) a = b;
}
template <class T>
void chmax(T& a, const T& b) {
  if (a < b) a = b;
}
namespace std {
template <class S, class T>
ostream& operator<<(ostream& out, const pair<S, T>& a) {
  out << '(' << a.first << ',' << a.second << ')';
  return out;
}
}  // namespace std
long long int readL() {
  long long int res;
  scanf("%I64d", &res);
  return res;
}
void printL(long long int res) { printf("%I64d", res); }
const long long int INF = 2e18;
int n;
const int B = 300;
const int L = 100000 / B + 5;
int ar[100005];
struct sqdecom {
  struct point {
    long long int a, b;
    int id;
  };
  long long int suf[L];
  vector<point> line[L];
  vector<int> order[L];
  bool valid[100005];
  int invsum2[L];
  void getorder(int b) {
    for (int i = (b * B); i < (min(n, (b + 1) * B)); ++i) order[b].push_back(i);
    sort((order[b]).begin(), (order[b]).end(),
         [&](int a, int b) { return ar[a] < ar[b]; });
    ;
    ;
    debug((order[b]).begin(), (order[b]).end());
  }
  void push(vector<point>& line, long long int a, long long int b, int id) {
    ;
    ;
    ;
    ;
    ;
    ;
    while (!line.empty()) {
      point l1 = line.back();
      if (l1.a == a && l1.b >= b)
        return;
      else if (l1.b < b) {
        line.pop_back();
        continue;
      }
      if (line.size() == 1) break;
      point l2 = line[line.size() - 2];
      if ((l1.b - b) * (l1.a - l2.a) < (l2.b - l1.b) * (a - l1.a)) {
        line.pop_back();
        continue;
      } else {
        break;
      }
    }
    line.push_back((point){a, b, id});
  }
  int seek[L];
  void construct(int b) {
    seek[b] = 0;
    long long int latsum[B + 5] = {0};
    int invsum[B + 5] = {0};
    for (int i = min(n, (b + 1) * B) - b * B - 1; i >= 0; --i) {
      latsum[i] = latsum[i + 1] + (!valid[i + b * B] ? ar[i + b * B] : 0);
    }
    for (int i = (b * B); i < (min(n, (b + 1) * B)); ++i) {
      invsum[i + 1 - b * B] = invsum[i - b * B] + (!valid[i]);
    }
    debug(valid, valid + n);
    line[b].clear();
    for (auto i : order[b]) {
      if (valid[i]) {
        push(line[b], ar[i],
             latsum[i - b * B] + invsum[i - b * B] * (long long int)ar[i], i);
      }
    }
    for (auto p : line[b]) {
      ;
      ;
      ;
      ;
      ;
      ;
    }
  }
  int mx;
  void init() {
    mx = (n - 1) / B + 1;
    for (int i = 0; i < (n); ++i) valid[i] = 1;
    for (int i = 0; i < (n); ++i)
      if (i % B == 0) {
        getorder(i / B);
        construct(i / B);
      }
  }
  long long int eval(point p, long long int bef) {
    return p.a * (bef + 1) + p.b;
  }
  long long int findmax() {
    pair<long long int, int> res = make_pair(-INF, -1);
    for (int i = 0; i < n; i += B) {
      int b = i / B;
      if (line[b].empty()) {
        continue;
      }
      while (seek[b] + 1 < line[b].size() &&
             eval(line[b][seek[b]], invsum2[b]) <
                 eval(line[b][seek[b] + 1], invsum2[b])) {
        ++seek[b];
      }
      chmax(res, make_pair(eval(line[b][seek[b]], invsum2[b]) + suf[b], b));
    }
    int id = line[res.second][seek[res.second]].id;
    valid[id] = false;
    ;
    ;
    ;
    ;
    ;
    ;
    for (int i = 0; i < (res.second); ++i) suf[i] += ar[id];
    for (int i = (res.second + 1); i < (mx); ++i) invsum2[i]++;
    debug(invsum2, invsum2 + mx);
    construct(res.second);
    return res.first;
  }
};
sqdecom data;
int main() {
  cin >> n;
  for (int i = 0; i < (n); ++i) cin >> ar[i];
  data.init();
  long long int res = 0;
  long long int sum = 0;
  for (int i = 0; i < (n); ++i) {
    sum += data.findmax();
    ;
    ;
    chmax(res, sum);
  }
  cout << res << endl;
  return 0;
}
