Problem p03940 (C++)

Buggy submission (status: Runtime Error):
#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <vector>
#define maxn 500009
#define lson 1, m, rt << 1
#define rson m + 1, r, rt << 1 | 1
using namespace std;
const long long INF = 1e18;
long long tree[maxn];
int n, E, T;
long long a[maxn], dp[maxn];
long long f[maxn];
void pushup(int rt) { tree[rt] = min(tree[rt << 1], tree[rt << 1 | 1]); }
void build(int l, int r, int rt) {
  tree[rt] = INF;
  if (l == r) {
    return;
  }
  int m = (l + r) >> 1;
  build(lson);
  build(rson);
}
void update(int L, int R, long long val, int l, int r, int rt) {
  if (L <= l && r <= R) {
    tree[rt] = min(tree[rt], val);
    return;
  }
  int m = (l + r) >> 1;
  if (L <= m)
    update(L, R, val, lson);
  if (R > m)
    update(L, R, val, rson);
  pushup(rt);
}
long long query(int L, int R, int l, int r, int rt) {
  if (L <= l && r <= R)
    return tree[rt];
  long long res1 = INF, res2 = INF;
  int m = (l + r) >> 1;
  if (L <= m)
    res1 = query(L, R, lson);
  if (R > m)
    res2 = query(L, R, rson);
  return min(res1, res2);
}
int main() {
  cin >> n >> E >> T;
  for (int i = 1; i <= n; i++)
    cin >> a[i];
  build(1, n, 1);
  dp[0] = 0;
  update(1, 1, dp[0] - a[0], 1, n, 1);
  dp[0] = 0;
  f[0] = INF;
  for (int i = 1; i <= n; i++) {
    int L = 1, R = i;
    while (L < R) {
      int M = (L + R) >> 1;
      if (2LL * (a[i] - a[M]) <= T)
        R = M;
      else
        L = M + 1;
    }
    long long res = query(R, i, 1, n, 1);
    dp[i] = res + a[i] + T;
    if (R > 1) {
      dp[i] = min(dp[i], f[R - 1] + 3 * a[i]);
    }
    f[i] = min(f[i - 1], dp[i - 1] + a[i] - a[i - 1] - 3 * a[i]);
    update(i + 1, i + 1, dp[i] - a[i], 1, n, 1);
  }
  cout << dp[n] + E - a[n] << endl;
  // system("pause");
  return 0;
}

Fixed submission:
#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <vector>
#define maxn 500009
#define lson l, m, rt << 1
#define rson m + 1, r, rt << 1 | 1
using namespace std;
const long long INF = 1e18;
long long tree[maxn];
int n, E, T;
long long a[maxn], dp[maxn];
long long f[maxn];
void pushup(int rt) { tree[rt] = min(tree[rt << 1], tree[rt << 1 | 1]); }
void build(int l, int r, int rt) {
  tree[rt] = INF;
  if (l == r) {
    return;
  }
  int m = (l + r) >> 1;
  build(lson);
  build(rson);
}
void update(int L, int R, long long val, int l, int r, int rt) {
  if (L <= l && r <= R) {
    tree[rt] = min(tree[rt], val);
    return;
  }
  int m = (l + r) >> 1;
  if (L <= m)
    update(L, R, val, lson);
  if (R > m)
    update(L, R, val, rson);
  pushup(rt);
}
long long query(int L, int R, int l, int r, int rt) {
  if (L <= l && r <= R)
    return tree[rt];
  long long res1 = INF, res2 = INF;
  int m = (l + r) >> 1;
  if (L <= m)
    res1 = query(L, R, lson);
  if (R > m)
    res2 = query(L, R, rson);
  return min(res1, res2);
}
int main() {
  cin >> n >> E >> T;
  for (int i = 1; i <= n; i++)
    cin >> a[i];
  build(1, n, 1);
  dp[0] = 0;
  update(1, 1, dp[0] - a[0], 1, n, 1);
  dp[0] = 0;
  f[0] = INF;
  for (int i = 1; i <= n; i++) {
    int L = 1, R = i;
    while (L < R) {
      int M = (L + R) >> 1;
      if (2LL * (a[i] - a[M]) <= T)
        R = M;
      else
        L = M + 1;
    }
    long long res = query(R, i, 1, n, 1);
    dp[i] = res + a[i] + T;
    if (R > 1) {
      dp[i] = min(dp[i], f[R - 1] + 3 * a[i]);
    }
    f[i] = min(f[i - 1], dp[i - 1] + a[i] - a[i - 1] - 3 * a[i]);
    update(i + 1, i + 1, dp[i] - a[i], 1, n, 1);
  }
  cout << dp[n] + E - a[n] << endl;
  // system("pause");
  return 0;
}