#include <bits/stdc++.h>
using namespace std;

#ifdef LOCAL
#include "dump.hpp"
#else
#define dump(...)
#define dumpv(...)
#endif

#define rep(i, n) for (int i = 0; i < (n); i++)
#define mins(x, y) (x = min(x, y))
#define maxs(x, y) (x = max(x, y))
using ll = long long;
using vi = vector<int>;
using vl = vector<ll>;
using vvi = vector<vi>;
using vvl = vector<vl>;
using P = pair<int, int>;
const int MOD = 1e9 + 7;
const int INF = 1001001001;
const ll LINF = 1001002003004005006ll;

enum queryType { SUM, MAX, MIN };
template<typename T>
struct SegTree {
  int n;
  T init; // 単位元(初期値)
  vector<T> node;
  function<T(T&, T&)> calc; // 子ノード2つから親ノードのデータにする処理
  SegTree(int sz, queryType qtype) : n(1) {
    // 初期値と処理関数の設定
    switch (qtype) {
      case SUM:
        init = 0;
        calc = [](T& v1, T& v2) { return v1 + v2; };
        break;
      case MAX:
        init = std::numeric_limits<T>::lowest();
        calc = [](T& v1, T& v2) { return (v1 > v2) ? v1 : v2; };
        break;
      case MIN:
        init = std::numeric_limits<T>::max();
        calc = [](T& v1, T& v2) { return (v1 < v2) ? v1 : v2; };
        break;
    }
    while (n < sz) n *= 2; // 最下段のノード数は2のべき乗(n)
    node.resize(2 * n - 1, init); // セグメント木全体で必要なノード数は2n-1個である
  }
  SegTree(vector<T>& v, queryType qtype) : SegTree(v.size(), qtype) {
    // 最下段に値を入れたあとに、下の段から順番に値を入れる
    // 値を入れるには、自分の子の2値を参照すれば良い
    // ノードiの親は(i-1)/2、子は(2i+1,2i+2)で見つける
    for (int i = 0; i < v.size(); i++) node[i + n - 1] = v[i];
    for (int i = n - 2; i >= 0; i--) node[i] = calc(node[2 * i + 1], node[2 * i + 2]);
  }
  void update(int i, T v) {
    i += (n - 1); // 最下段のノードにアクセスする
    // 最下段のノードを更新したら、あとは親に上って更新していく
    node[i] = v;
    while (i > 0) {
      i = (i - 1) / 2; // 1つ親にする
      node[i] = calc(node[2 * i + 1], node[2 * i + 2]);
    }
  }
  // 要求区間 [a, b) 中の要素の最小値を答える
  // k := 自分がいるノードのインデックス、対象区間は [l, r) にあたる
  T query(int a, int b, int k = 0, int l = 0, int r = -1) {
    // 最初に呼び出されたときの対象区間は [0, n)
    if (r < 0) r = n;
    // 要求区間と対象区間が交わらない -> 適当に返す
    if (r <= a || b <= l) return init;
    // 要求区間が対象区間を完全に被覆 -> 対象区間を答えの計算に使う
    if (a <= l && r <= b) return node[k];
    // 要求区間が対象区間の一部を被覆 -> 子について探索を行う
    // 左側の子を vl ・ 右側の子を vr としている
    // 新しい対象区間は、現在の対象区間を半分に割ったもの
    T vl = query(a, b, 2 * k + 1, l, (l + r) / 2);
    T vr = query(a, b, 2 * k + 2, (l + r) / 2, r);
    return calc(vl, vr);
  }
};

void solve() {
  int n;
  cin >> n;
  vi a(n);
  rep(i, n) cin >> a[i];
  vl c(n + 1);
  vl m(n + 1);
  rep(i, n) c[i + 1] += c[i] + a[i];
  rep(i, n) m[i + 1] = max(m[i], c[i] + a[i]);
  dump(a);
  dump(c);
  dump(m);
  ll x = 0;
  ll ans = -INF;
  rep(i, n) {
    ll nx = x + m[i];
    maxs(ans, nx);
    x += c[i + 1];
    maxs(ans, x);
  }
  cout << ans << endl;
}

int main() {
  cin.tie(0);
  ios::sync_with_stdio(false);
  cout << fixed << setprecision(15);
  // freopen("temp.1", "r", stdin);
  solve();
  return 0;
}
#include <iostream>
#include <vector>
#include <cmath>
#include <algorithm>
using namespace std;
typedef long long ll;
ll mod = 1000000007;
 
int main() {
    ll N,cnt=0,S = 0;
    cin >> N;
    vector<ll> A(N);
    for(int i=0; i<N; i++){
        cin >> A[i];
        S += A[i];
    }
    sort(A.begin(),A.end());
    for(int i=0; i<N-1; i++){
        S -= A[i];
        cnt += S - (A[i] * (N-i-1));
    }

    cout << cnt;
}