Cod sursa(job #2295111)

Utilizator MiricaMateiMirica Matei MiricaMatei Data 3 decembrie 2018 09:07:15
Problema Euro Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.32 kb
#include <bits/stdc++.h>

using namespace std;

const int MAXN = 100005;
const long long INF = (1LL << 62) - 1;

typedef long long T;

struct Line {
  T a, b;
  mutable double x;

  Line(T _a, T _b) : a(_a), b(_b), x(INF) {}

  Line(T _x) : a(0), b(0), x(_x) {}

  T eval(T x) const {
    return a * x + b;
  }

  static bool compare;
  friend bool operator < (const Line& l1, const Line& l2) {
    if (compare == true) {
      if (l1.a == l2.a)
        return l1.b < l2.b;
      return l1.a < l2.a;
    } else {
      return l1.x < l2.x;
    }
  }

  friend double intersect(const Line& l1, const Line& l2) {
    if (l1.a == l2.a)
      exit(0);
    return ((double)l2.b - l1.b) / (l1.a - l2.a);
  }
};

bool Line::compare = true;

class CHT : public set<Line> {
  public:
    void Insert(const Line& l) {
      pair<iterator, bool> it = insert(l);
      if (it.second == false)
        return ;
      if (del(it.first)) {
        erase(it.first);
        return ;
      }

      while (it.first != begin() && del(prev(it.first)))
        erase(prev(it.first));
      while (next(it.first) != end() && del(next(it.first)))
        erase(next(it.first));
      recompute(it.first);
      if (it.first != begin())
        recompute(prev(it.first));
    }

    T Query(const T& x) {
      Line::compare = false;
      T ans = lower_bound(x)->eval(x);
      Line::compare = true;
      return ans;
    }

    void parc() {
      for (auto it:(*this))
        printf("%lld %lld\n", it.a, it.b);
    }

  private:
    bool del(iterator it) {
      if (next(it) == end())
        return false;
      if (next(it)->a == it->a)
        return true;
      if (it == begin())
        return false;
      return intersect(*prev(it), *next(it)) >= intersect(*it, *next(it));
    }

    void recompute(iterator it) {
      if (next(it) == end())
        it->x = INF;
      else
        it->x = intersect(*it, *next(it));
    }
};

int main() {
  freopen("euro.in", "r", stdin);
  freopen("euro.out", "w", stdout);

  CHT bt;
  int n, t;
  scanf("%d%d", &n, &t);
  T ans = 0, s = 0;
  for (int i = 1; i <= n; ++i) {
    int x;
    scanf("%d", &x);
    bt.Insert(Line(-s, ans));
    s += x;
    ans = bt.Query(i);
    ans += s * i - t;
  }

  printf("%lld\n", ans);

  return 0;
}