Cod sursa(job #2442224)

Utilizator AlexPop28Pop Alex-Nicolae AlexPop28 Data 23 iulie 2019 12:56:27
Problema Euro Scor 100
Compilator cpp-64 Status done
Runda Lista lui wefgef Marime 2.07 kb
#include <bits/stdc++.h>
#define DEBUG(x) cerr << (#x) << ": " << (x) << '\n'

using namespace std;

template<class T, bool maximum>
struct LiChao {
  struct Line {
    T a, b;
    Line(T a_ = 0, T b_ = 0) : a(a_), b(b_) {}
    T operator()(T x) {
      return a * x + b;
    }
  };
  int n;
  vector<Line> tree;
  vector<T> queries;
  LiChao(vector<T> &queries_) : n(queries_.size()), queries(queries_) {
    int sz = 1;
    while (sz < n) {
      sz <<= 1;
    }
    tree.resize(2 * sz - 1);
  }
  bool Compare(T a, T b) {
    if (maximum) return a > b;
    return a < b;
  }
  void Update(int node, int left, int right, Line nline) {
    int mid = left + (right - left) / 2;
    T lf = queries[left];
    T md = queries[mid];
    bool l = Compare(nline(lf), tree[node](lf));
    bool m  = Compare(nline(md), tree[node](md));
    if (m) {
      swap(tree[node], nline);
    }
    if (left == right) {
      return;
    }
    if (l != m) {
      Update(2 * node + 1, left, mid, nline);
    } else {
      Update(2 * node + 2, mid + 1, right, nline);
    }
  }
  T Query(int node, int left, int right, int pos) {
    T curr = tree[node](queries[pos]);
    if (left == right) {
      return curr;
    }
    int mid = left + (right - left) / 2;
    if (pos <= mid) {
      return max(curr, Query(2 * node + 1, left, mid, pos));
    } else {
      return max(curr, Query(2 * node + 2, mid + 1, right, pos));
    }
  }
  void Update(T a, T b) {
    Update(0, 0, n - 1, Line(a, b));
  }
  T Query(T x) {
    int pos = lower_bound(queries.begin(), queries.end(), x) - queries.begin();
    assert(queries[pos] == x);
    return Query(0, 0, n - 1, pos);
  }
};

int main() {
  ifstream cin("euro.in");
  ofstream cout("euro.out");

  int n, t; cin >> n >> t;
  vector<int> v(n);
  for (int i = 0; i < n; ++i) {
    cin >> v[i];
  }
  vector<long long> queries(n);
  iota(queries.begin(), queries.end(), 1);
  LiChao<long long, true> cht(queries);
  long long sum = 0LL, dp;
  for (int i = 0; i < n; ++i) {
    sum += v[i];
    dp = cht.Query(i + 1) + sum * (i + 1) - t;
    cht.Update(-sum, dp);
  }
  cout << dp << endl;
}