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

#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <stack>
#include <vector>
using namespace std;
typedef long long ll;
typedef pair<ll, ll> P;
typedef double db;

#define fr first
#define sc second
#define pb push_back
#define rep(i, x) for (ll i = 0; i < x; i++)
#define rep1(i, x) for (ll i = 1; i <= x; i++)
#define rrep(i, x) for (ll i = x - 1; i >= 0; i--)
#define rrep1(i, x) for (ll i = x; i > 0; i--)

const ll INF = 0xfffffffffffffff;
struct T {
  ll val, min, max;
};

T dp[2][1001]; //
T(*prv);
T(*nxt);
ll N, M, K;
ll A[20001];
ll valmin[20001];

int main() {
  scanf("%lld%lld%lld", &N, &M, &K);
  rep(i, N) scanf("%lld", &A[i]);
  fill(dp[0], dp[2], T{INF, INF, -INF});
  prv = dp[0];
  nxt = dp[1];
  prv[1] = T{K, A[0], A[0]};
  valmin[0] = K;
  rep(i, N - 1) {
    rep(j, M + 1) nxt[j] = T{INF, INF, -INF};
    valmin[i + 1] = nxt[1].val = valmin[i] + K;
    nxt[1].min = nxt[1].max = A[i + 1];

    rep1(j, M - 1) {
      if (prv[j].val == INF)
        continue;
      nxt[j + 1] = prv[j];
      if (prv[j].min <= A[i + 1] && A[i + 1] <= prv[j].max) {
        nxt[j + 1].val += (nxt[j + 1].max - nxt[j + 1].min);
      } else if (prv[j].max < A[i + 1]) {
        nxt[j + 1].max = A[i + 1];
        nxt[j + 1].val += (A[i + 1] - prv[j].max) * j;
        nxt[j + 1].val += (nxt[j + 1].max - nxt[j + 1].min);
      } else {
        nxt[j + 1].min = A[i + 1];
        nxt[j + 1].val += (prv[j].min - A[i + 1]) * j;
        nxt[j + 1].val += (nxt[j + 1].max - nxt[j + 1].min);
      }
      valmin[i + 1] = min(valmin[i + 1], nxt[j + 1].val);
    }
    swap(nxt, prv);
  }
  printf("%lld\\n", valmin[N - 1]);
}

Error: TLE

Fixed submission:

#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <stack>
#include <vector>
using namespace std;
typedef long long ll;
typedef pair<ll, ll> P;
typedef double db;

#define fr first
#define sc second
#define pb push_back
#define rep(i, x) for (ll i = 0; i < x; i++)
#define rep1(i, x) for (ll i = 1; i <= x; i++)
#define rrep(i, x) for (ll i = x - 1; i >= 0; i--)
#define rrep1(i, x) for (ll i = x; i > 0; i--)
const ll INF = 0xfffffffffffffff;
const P PINF = P(INF, -INF);
P dat[80000]; // min max
ll n;

void init(ll n_) {
  n = 1;
  while (n < n_)
    n *= 2;
  rep(i, 2 * n - 1) dat[i] = P(INF, -INF);
  return;
}

void update(ll x, ll a) {
  x += n - 1;
  dat[x] = P(a, a);
  while (x > 0) {
    x = (x - 1) / 2;
    dat[x] = P(min(dat[x * 2 + 1].fr, dat[x * 2 + 2].fr),
               max(dat[x * 2 + 1].sc, dat[x * 2 + 2].sc));
  }
  return;
}

P query(ll a, ll b, ll k, ll l, ll r) {
  if (b <= l || r <= a)
    return PINF;
  if (a <= l && r <= b)
    return dat[k];
  P chl = query(a, b, k * 2 + 1, l, (l + r) / 2);
  P chr = query(a, b, k * 2 + 2, (l + r) / 2, r);
  return P(min(chl.fr, chr.fr), max(chl.sc, chr.sc));
}

ll N, M, K;
ll A[20000];

ll dp[20000]; // i???????????§?????±??°?????????????°??????????

ll calc(ll id, ll kosu) { // id?????§kosu
  ll res = 0;
  if (id - kosu >= 0)
    res += dp[id - kosu];
  P p = query(id - kosu + 1, id + 1, 0, 0, n);
  res += (p.sc - p.fr) * kosu + K;
  // if(res<0) cout<<id<<" "<<kosu<<" "<<p.fr<<" "<<p.sc<<endl;
  return res;
}

int main() {
  scanf("%lld%lld%lld", &N, &M, &K);
  init(N);
  rep(i, N) {
    scanf("%lld", &A[i]);
    update(i, A[i]);
    dp[i] = INF;
  }
  rep(i, N) {
    rep1(j, M) {
      if (i + 1 < j)
        continue;
      dp[i] = min(dp[i], calc(i, j));
    }
  }
  printf("%lld\\n", dp[N - 1]);
  // rep(i,n*2-1) cout<<i<<"="<<dat[i].fr<<dat[i].sc<<endl;
}