Problem p00548 (C++) — buggy submission, verdict: Time Limit Exceeded

#include <bits/stdc++.h>

using namespace std;

typedef long long ll;

const ll INF = (1LL << 55);

struct SegmentTree {
  vector<ll> mini, maxi;
  int sz;
  SegmentTree(int n) {
    sz = 1;
    while (sz < n)
      sz *= 2;
    mini.resize(2 * sz - 1, INF);
    maxi.resize(2 * sz - 1, -INF);
  }
  void update(int k, ll x) {
    k += sz - 1;
    mini[k] = x;
    maxi[k] = x;
    while (k > 0) {
      k = (k - 1) / 2;
      mini[k] = min(mini[2 * k + 1], mini[2 * k + 2]);
      maxi[k] = max(maxi[2 * k + 1], maxi[2 * k + 2]);
    }
  }
  ll minimum(int a, int b, int k, int l, int r) {
    if (r <= a || b <= l)
      return INF;
    if (a <= l && r <= b)
      return mini[k];
    ll vl = minimum(a, b, 2 * k + 1, l, (l + r) / 2);
    ll vr = minimum(a, b, 2 * k + 2, (l + r) / 2, r);
    return min(vl, vr);
  }
  ll maximum(int a, int b, int k, int l, int r) {
    if (r <= a || b <= l)
      return -INF;
    if (a <= l && r <= b)
      return maxi[k];
    ll vl = maximum(a, b, 2 * k + 1, l, (l + r) / 2);
    ll vr = maximum(a, b, 2 * k + 2, (l + r) / 2, r);
    return max(vl, vr);
  }
  ll minimum(int a, int b) { return minimum(a, b, 0, 0, sz); }
  ll maximum(int a, int b) { return maximum(a, b, 0, 0, sz); }
};

int main() {
  ll N, M, K, A[20010];
  cin >> N >> M >> K;
  SegmentTree seg(N);
  for (int i = 0; i < N; i++) {
    cin >> A[i];
  }
  ll dp[20010];
  fill(dp, dp + 20010, INF);
  dp[0] = 0;
  for (int i = 0; i < N; i++) {
    ll maxi = -INF, mini = INF;
    for (int j = 1; j <= min(M, N - i); j++) {
      maxi = max(maxi, A[i + j - 1]);
      mini = min(mini, A[i + j - 1]);
      ll dif = maxi - mini;
      dp[i + j] = min(dp[i + j], dp[i] + K + j * dif);
    }
  }
  cout << dp[N] << endl;
  return 0;
}

Error: TLE

Fixed submission:

#include <bits/stdc++.h>

using namespace std;

typedef long long ll;

const ll INF = (1LL << 55);

struct SegmentTree {
  vector<ll> mini, maxi;
  int sz;
  SegmentTree(int n) {
    sz = 1;
    while (sz < n)
      sz *= 2;
    mini.resize(2 * sz - 1, INF);
    maxi.resize(2 * sz - 1, -INF);
  }
  void update(int k, ll x) {
    k += sz - 1;
    mini[k] = x;
    maxi[k] = x;
    while (k > 0) {
      k = (k - 1) / 2;
      mini[k] = min(mini[2 * k + 1], mini[2 * k + 2]);
      maxi[k] = max(maxi[2 * k + 1], maxi[2 * k + 2]);
    }
  }
  ll minimum(int a, int b, int k, int l, int r) {
    if (r <= a || b <= l)
      return INF;
    if (a <= l && r <= b)
      return mini[k];
    ll vl = minimum(a, b, 2 * k + 1, l, (l + r) / 2);
    ll vr = minimum(a, b, 2 * k + 2, (l + r) / 2, r);
    return min(vl, vr);
  }
  ll maximum(int a, int b, int k, int l, int r) {
    if (r <= a || b <= l)
      return -INF;
    if (a <= l && r <= b)
      return maxi[k];
    ll vl = maximum(a, b, 2 * k + 1, l, (l + r) / 2);
    ll vr = maximum(a, b, 2 * k + 2, (l + r) / 2, r);
    return max(vl, vr);
  }
  ll minimum(int a, int b) { return minimum(a, b, 0, 0, sz); }
  ll maximum(int a, int b) { return maximum(a, b, 0, 0, sz); }
};

int main() {
  ll N, M, K;
  cin >> N >> M >> K;
  SegmentTree seg(N);
  for (int i = 0; i < N; i++) {
    int A;
    cin >> A;
    seg.update(i, A);
  }
  ll dp[20010];
  fill(dp, dp + 20010, INF);
  dp[0] = 0;
  for (int i = 0; i < N; i++) {
    for (int j = min(M, N - i); j > 0; j--) {
      ll dif = seg.maximum(i, i + j) - seg.minimum(i, i + j);
      dp[i + j] = min(dp[i + j], dp[i] + K + j * dif);
    }
  }
  cout << dp[N] << endl;
  return 0;
}