Cod sursa(job #1114381)

Utilizator ZeusCatalin Tiseanu Zeus Data 21 februarie 2014 16:16:36
Problema Avioane Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 4.53 kb
/*
 Catalin-Stefan Tiseanu
 
 Pre-written code is assembled from various sources found online.
 Big thanks to the community for that !
 */

// Pre-written code below

using namespace std;

#include <algorithm>
#include <bitset>
#include <cassert>
#include <cctype>
#include <climits>
#include <cmath>
#include <complex>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <deque>
#include <fstream>
#include <functional>
#include <iomanip>
#include <iostream>
#include <limits>
#include <list>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <utility>
#include <vector>

#include <unordered_map>

//#define DEBUG

#ifdef DEBUG
#define debug(args...)            {dbg,args; cerr<<endl;}
#else
#define debug(args...)              // Just strip off all debug tokens
#endif

struct debugger
{
  template<typename T> debugger& operator , (const T& v)
  {
  cerr<<v<<" ";
  return *this;
  }
} dbg;

// templates
template<typename T> int size(const T& c) { return int(c.size()); }
template<typename T> T abs(T x) { return x < 0 ? -x : x; }
template<typename T> T sqr(T x) { return x*x; }
template<typename T> bool remin(T& x, T y) { if (x <= y) return false; x = y; return true; }
template<typename T> bool remax(T& x, T y) { if (x >= y) return false; x = y; return true; }

// misc
#define EPSILON              1e-7

// types
typedef long long            int64;
typedef unsigned long long   uint64;

// shortcuts
#define all(_xx)             _xx.begin(), _xx.end()

#define pb                   push_back
#define vi                   vector<int>
#define vpii                 vector<pair<int,int> >
#define vpdd                 vector<paid<double,double> >

#define pii                  pair<int,int>
#define pdd                  pair<double, double>
#define mp(XX, YY)           make_pair(XX, YY)
#define fi                   first
#define se                   second

#define ll                   long long
#define SS                   stringstream

// for loops
#define re(II, NN)           for (int II(0), _NN(NN); (II) < (NN); ++(II))
#define fod(II, XX, YY)      for (int II(XX), _YY(YY); (II) >= (_YY); --(II))
#define fo(II, XX, YY)       for (int II(XX), _YY(YY); (II) <= (_YY); ++(II))
#define foreach(it,c) for(__typeof((c).begin()) it=(c).begin();it!=(c).end();++it)

// Useful hardware instructions
#define bitcount             __builtin_popcount
#define gcd                  __gcd

// Useful all around
#define checkbit(n,b)        ( (n >> b) & 1)
#define DREP(a)              sort(all(a));a.erase(unique(all(a)),a.end())
#define INDEX(arr,ind)       (lower_bound(all(arr),ind)-arr.begin())

// Code written during the competition below

#define MAX_N (1<<17)

// general struct to solve dp of the form
// E[j] = min (1 <= i < j) D[i] + w(i, j)

struct ConvexDP {
  inline int query(int i) {
    
  }
  
  inline int insert(int i, int new_d) {
    
  }
  
  // what is the minimum index k, k < h <= n, s.t C(l, h) <= C(k, h)
  inline int get_h(int l, int k) {
    
  }
  
  // this needs to be defined for a problem
  int C(int k, int l) {
    
  }
};

int N, A[MAX_N];
int64 res = 0;

void do_test() {
  freopen("avioane_big.in", "w", stdout);
  
  N = 100000;
  
  printf("%d\n", N);
  fo (i, 1, N)
    printf("%d ", rand() % 2000000000);
  
  printf("\n");
}

int64 calc(int a_min, int a_max, int b_min, int b_max) {
  if (b_min > b_max || a_min > a_max)
    return 0;
  
  debug(a_min, a_max, b_min, b_max);
  
  int b_mid = (b_min + b_max) >> 1;
  a_min = max(a_min, b_min);
  
  
  int64 cur_val(0), l_val(0), r_val(0), best_pos = -1;
  
  fo (a, max(b_mid, a_min), a_max) {
    int64 cur_pos = ((int64)N - a + 1) * A[a] + ((int64)a - b_mid) * A[b_mid];
    if (cur_pos > cur_val) {
      cur_val = cur_pos;
      best_pos = a;
    }
  }
  
  return max(cur_val,
                   max(calc(a_min, best_pos, b_min, b_mid - 1),
                       calc(best_pos, a_max, b_mid + 1, b_max))
                                                                 );
}

// key observation opt(i) <= opt(j) for i <= j
void solve() {
  sort(A + 1, A + N + 1);
  res = calc(1, N, 1, N);
}

void brute_test() {
  int64 cur = 0;
  fo (i, 1, N)
    fo (j, i + 1, N)
      cur = max(cur, (int64)i * A[i] + (int64)(j - i) * A[j]);
  assert(res == cur);
}

void read() {
  freopen("avioane.in", "r", stdin);
  scanf("%d", &N);
  fo (i, 1, N)
    scanf("%d ", &A[i]);
}

void write() {
  freopen("avioane.out", "w", stdout);
  cout << res << endl;
}

int main() {;
  read();
  solve();
  //brute_test();
  write();
  
  return 0;
}