Cod sursa(job #2707915)

Utilizator retrogradLucian Bicsi retrograd Data 17 februarie 2021 22:37:47
Problema Euro Scor 30
Compilator cpp-64 Status done
Runda Lista lui wefgef Marime 1.71 kb
#include <bits/stdc++.h>
 
using namespace std;

using ll = long long;
const ll INF = 2e18;
struct Line { long long a, b; };

ll Floor(ll a, ll b) { return a / b - (a % b < 0); }
 
struct KinTour {
  struct Node { int dp = 0; ll ev = INF; };
  
  int n; ll t = -INF;
  vector<Node> T; vector<Line> L;

  KinTour(int n) : n(n), T(2 * n), L(n, Line{0, 0}) {}

  ll eval(int i) { return L[i].a * t + L[i].b; }
  ll inter(int i, int j) {
    assert(eval(i) >= eval(j));
    if (L[i].a >= L[j].a) return INF;
    return 1 + Floor(L[i].b - L[j].b, L[j].a - L[i].a);
  }
  void go(int x, int b, int e, int l, int r) {
    if (e <= l || b >= r || T[x].ev < t) return;
    if (e - b == 1) { T[x].dp = b; return; }
    int m = (b + e) / 2, z = x + 2 * (m - b);
    go(x + 1, b, m, l, r); go(z, m, e, l, r);
    int i = T[x + 1].dp, j = T[z].dp;
    if (eval(i) < eval(j)) swap(i, j);
    T[x].dp = i; T[x].ev = min({T[x + 1].ev, T[z].ev, inter(i, j)});
  }
  ll EvalMax(ll t) {
    assert(t >= this->t);
    this->t = t; go(1, 0, n, 0, n);
    return eval(T[1].dp);
  }
  void Update(int i, Line l) { 
    L[i] = l; go(1, 0, n, i, i); 
  }
};
 
int main() {
  ifstream cin("euro.in");
  ofstream cout("euro.out");
  int n, t;
  cin >> n >> t;

  // dp[i] = max_j(dp[j] + (gain[i] - gain[j]) * i - t)
  // dp[i] = max_j(dp[j] - gain[j] * i + gain[i] * i - t)
  // dp[i] = gain[i] * i - t + max_j(dp[j] - gain[j] * i)
  // solution: keep stack of linear functions of type
  //           -gain[j] * X + dp[j]
  // no monotony -> need set

  ll ans = 0, gain = 0;
  KinTour kt(n + 1);
  for (int i = 1; i <= n; ++i) {
    int x; cin >> x; gain += x;
    ans = kt.EvalMax(i) + gain * i - t;
    kt.Update(i, Line{-gain, ans});
  }
  cout << ans << endl;
  return 0;
}