Cod sursa(job #1747827)

Utilizator depevladVlad Dumitru-Popescu depevlad Data 25 august 2016 17:30:20
Problema Euro Scor 25
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.38 kb
#include <cstdio>
#include <algorithm>

using namespace std;

const int kMaxN = 35000;

int n, t, deq_left, deq_right;
int euro[kMaxN];
int deq[kMaxN];
int64_t best[kMaxN];
int64_t s_euro[kMaxN];
int64_t a[kMaxN], b[kMaxN];

double Intersect(int i, int j) {
  if(a[i] == a[j]) return 1e20;
  return 1.0 * (b[j] - b[i]) / (a[i] - a[j]);
}

void PushLine(int i) {
  while(deq_right - deq_left > 1) {
    double x0 = Intersect(deq[deq_right - 2], deq[deq_right - 1]);
    double x1 = Intersect(deq[deq_right - 1], i);
    if(x0 < x1) deq_right--;
    else break;
  }
  deq[deq_right++] = i;
}

int64_t GetMax(int x) {
  while(deq_left < deq_right) {
    int64_t v0 = a[deq[deq_left]] * x + b[deq[deq_left]];
    int64_t v1 = a[deq[deq_left + 1]] * x + b[deq[deq_left + 1]];
    if(v0 <= v1) deq_left++;
    else break;
  }
  return a[deq[deq_left]] * x + b[deq[deq_left]];
}

int main() {
  freopen("euro.in", "r", stdin);
  freopen("euro.out", "w", stdout);
  
  scanf("%d %d", &n, &t);
  for(int i = 1; i <= n; i++) {
    scanf("%d", &euro[i]);
    s_euro[i] = s_euro[i - 1] + euro[i];
  }
  
  deq_left = deq_right = 0;
  for(int i = 0; i <= n; i++) {
    if(deq_left == deq_right) best[i] = 0;
    else best[i] = GetMax(i) + s_euro[i] * i - t;
    a[i] = -(s_euro[i]);
    b[i] = best[i];
    PushLine(i);
  }

  printf("%lld\n", best[n]);
  return 0;
}