Cod sursa(job #2221399)

Utilizator andrei.arnautuAndi Arnautu andrei.arnautu Data 13 iulie 2018 23:10:05
Problema Avioane Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.41 kb
/**
  *  Worg
  */
#include <cstdio>
#include <algorithm>

FILE *fin = freopen("avioane.in", "r", stdin); FILE *fout = freopen("avioane.out", "w", stdout);

const int MAX_N = 1e5 + 5;

/*-------- Data --------*/
int n;
int arr[MAX_N];
int optimalIndex[MAX_N];
/*-------- --------*/

void ReadInput() {
  scanf("%d", &n);
  for(int i = 1; i <= n; i++) {
    scanf("%d", &arr[i]);
  }
}

void Divide(int left, int right) {
  if(left > right) return;

  int mid = (left + right) / 2;

  //  We iterate from optimalIndex[left - 1] to min(mid, optimalIndex[right + 1])

  optimalIndex[mid] = mid;
  for(int i = optimalIndex[left - 1]; i <= std::min(mid, optimalIndex[right + 1]); i++) {
    long long currentBest = 1LL * (mid - optimalIndex[mid] + 1) * arr[optimalIndex[mid]];
    long long currentValue = 1LL * (mid - i + 1) * arr[i];

    if(currentBest < currentValue) {
      optimalIndex[mid] = i;
    }
  }

  if(left < right) {
    Divide(left, mid - 1); 
    Divide(mid + 1, right);
  }
}

long long ComputeAnswer() {
  long long answer = 0;
  for(int i = 0; i <= n; i++) {
    long long candidate = 1LL * (i - optimalIndex[i] + 1) * arr[optimalIndex[i]] + 1LL * (n - i) * arr[i + 1];
    answer = std::max(answer, candidate);
  }

  return answer;
}

int main() {
  ReadInput();

  std::sort(arr + 1, arr + n + 1);
  optimalIndex[0] = 0; optimalIndex[n + 1] = n + 1;

  Divide(1, n);

  printf("%lld\n", ComputeAnswer());
  return 0;
}