Problem p03940 (C++)

Buggy submission (status: Runtime Error):
#include <algorithm>
#include <bitset>
#include <cmath>
#include <deque>
#include <functional>
#include <iomanip>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <string>
#include <vector>
#define vll vector<ll>
#define vvvl vector<vvl>
#define vvl vector<vector<ll>>
#define VV(a, b, c, d) vector<vector<d>>(a, vector<d>(b, c))
#define VVV(a, b, c, d) vector<vvl>(a, vvl(b, vll(c, d)));
#define re(c, b) for (ll c = 0; c < b; c++)
#define all(obj) (obj).begin(), (obj).end()
typedef long long int ll;
typedef long double ld;
using namespace std;

struct segtree {
  ll M = 1, INIT;
  vector<ll> dat;
  segtree(ll N, ll num) {
    INIT = num;
    while (M < N)
      M *= 2;
    for (int i = 0; i < M * 2 - 1; i++)
      dat.push_back(num);
  }
  void update(ll x, ll k, ll l = 0, int r = -1) {
    if (r == -1)
      r = M;
    k += M - 1;
    dat[k] = x;
    while (k > 0)
      k = (k - 1) / 2, dat[k] = min(dat[k * 2 + 1], dat[k * 2 + 2]);
  }
  ll query(ll a, ll b = -1, ll k = 0, ll l = 0, ll r = -1) {
    if (r == -1)
      r = M;
    if (b == -1)
      b = M;
    if (r <= a || b <= l)
      return INIT;
    if (a <= l && r <= b)
      return dat[k];
    ll A = query(a, b, k * 2 + 1, l, (l + r) / 2);
    ll B = query(a, b, k * 2 + 2, (l + r) / 2, r);
    return min(A, B);
  }
};
int main(int argc, char const *argv[]) {
  ll n, e, t;
  std::cin >> n >> e >> t;
  if (n > 2000)
    throw runtime_error("error");
  vll x(n + 1, -10000000000);
  re(i, n) scanf("%lld", &x[i + 1]);

  ll INF = 1000000000000000000;
  vll dp(n + 1, INF);
  dp[0] = e;
  segtree seg(n + 1, INF);
  seg.update(dp[0] - 2 * x[1], 0);

  for (int now = 1; now <= n; now++) {
    ll l = lower_bound(all(x), x[now] - t / 2) - x.begin();

    if (now != 1) {
      dp[now] = dp[max((ll)0, l - 1)] + t;
      dp[now] = min(dp[now], 2 * x[now] + seg.query(0, l - 1));
    } else {
      dp[now] = dp[0] + t;
    }
    if (now != n)
      seg.update(dp[now] - 2 * x[now + 1], now);
  }

  // std::cout << dp[1] << '\n';
  // std::cout << dp[2] << '\n';
  std::cout << dp[n] << '\n';
  return 0;
}


Fixed submission:
#include <algorithm>
#include <bitset>
#include <cmath>
#include <deque>
#include <functional>
#include <iomanip>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <string>
#include <vector>
#define vll vector<ll>
#define vvvl vector<vvl>
#define vvl vector<vector<ll>>
#define VV(a, b, c, d) vector<vector<d>>(a, vector<d>(b, c))
#define VVV(a, b, c, d) vector<vvl>(a, vvl(b, vll(c, d)));
#define re(c, b) for (ll c = 0; c < b; c++)
#define all(obj) (obj).begin(), (obj).end()
typedef long long int ll;
typedef long double ld;
using namespace std;

struct segtree {
  ll M = 1, INIT;
  vector<ll> dat;
  segtree(ll N, ll num) {
    INIT = num;
    while (M < N)
      M *= 2;
    for (int i = 0; i < M * 2 - 1; i++)
      dat.push_back(num);
  }
  void update(ll x, ll k, ll l = 0, int r = -1) {
    if (r == -1)
      r = M;
    k += M - 1;
    dat[k] = x;
    while (k > 0)
      k = (k - 1) / 2, dat[k] = min(dat[k * 2 + 1], dat[k * 2 + 2]);
  }
  ll query(ll a, ll b = -1, ll k = 0, ll l = 0, ll r = -1) {
    if (r == -1)
      r = M;
    if (b == -1)
      b = M;
    if (r <= a || b <= l)
      return INIT;
    if (a <= l && r <= b)
      return dat[k];
    ll A = query(a, b, k * 2 + 1, l, (l + r) / 2);
    ll B = query(a, b, k * 2 + 2, (l + r) / 2, r);
    return min(A, B);
  }
};
int main(int argc, char const *argv[]) {
  ll n, e, t;
  std::cin >> n >> e >> t;
  vll x(n + 1, -10000000000);
  re(i, n) scanf("%lld", &x[i + 1]);

  ll INF = 1000000000000000000;
  vll dp(n + 1, INF);
  dp[0] = e;
  segtree seg(n + 1, INF);
  seg.update(dp[0] - 2 * x[1], 0);

  for (int now = 1; now <= n; now++) {
    ll l = lower_bound(all(x), x[now] - t / 2) - x.begin();

    if (now != 1) {
      dp[now] = dp[max((ll)0, l - 1)] + t;
      dp[now] = min(dp[now], 2 * x[now] + seg.query(0, l - 1));
    } else {
      dp[now] = dp[0] + t;
    }
    if (now != n)
      seg.update(dp[now] - 2 * x[now + 1], now);
  }

  // std::cout << dp[1] << '\n';
  // std::cout << dp[2] << '\n';
  std::cout << dp[n] << '\n';
  return 0;
}