Cod sursa(job #2977928)

Utilizator AztecaVlad Tutunaru 2 Azteca Data 12 februarie 2023 17:20:35
Problema Avioane Scor 70
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 1.5 kb
#include <bits/stdc++.h>

using namespace std;

ifstream fin("avioane.in");
ofstream fout("avioane.out");

typedef long long ll;
const int N = (int) 1e5 + 7;
int a[N];

struct Line {
  int a;
  ll b;

  int eval(int x) {
    return (ll) a * x + b;
  }
};

struct Fraction {
  ll num;
  ll den;
};

Fraction x(const Line &l1, const Line &l2) {
  // l1.a * x + l1.b = y;
  // l2.a * x + l2.b = y;

  // l1.a * x + l1.b = l2.a * x + l2.b
  // l1.a * x - l2.a * x = l2.b - l1.b
  // (l1.a - l2.a) * x = l2.b - l1.b
  // x = (l2.b - l1.b) / (l1.a - l2.a)

  if (l1.a - l2.a > 0) {
    return {l2.b - l1.b, l1.a - l2.a};
  } else {
    return {-(l2.b - l1.b), -(l1.a - l2.a)};
  }
}

bool operator <= (const Fraction &a, const Fraction &b) {
  return a.num * b.den <= a.den * b.num;
}

deque<Line> DS;

void add(Line line) {
  while ((int) DS.size() >= 2 && x(DS.end()[-1], line) <= x(DS.end()[-2], DS.end()[-1])) {
    DS.pop_back();
  }
  DS.push_back(line);
}

ll query(int x) {
  while (DS.size() > 1 && DS[0].eval(x) <= DS[1].eval(x)) {
    DS.pop_front();
  }
  return DS[0].eval(x);
}

int main() {
  ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0);

  int n;
  fin >> n;
  for (int i = 0; i < n; i++) {
    fin >> a[i];
  }
  sort(a, a + n);
  ll ret = 0;
  for (int i = 0; i < n; i++) {
    if (a[i] != a[i - 1]) {
      add({a[i], -a[i] * (i - 1)});
    }
    ret = max(ret, query(i) + (n - i - 1) * a[i + 1]);
  }
  fout << ret;
  return 0;
}