Problem p04017 (C++)

Buggy submission (status: Runtime Error):
// tsukasa_diary's programing contest code template
#include <bits/stdc++.h>
using namespace std;
#define TSUKASA_DIARY_S_TEMPLATE
// define
#define for_(i, a, b) for (int i = (a); i < (b); ++i)
#define for_rev(i, a, b) for (int i = (a); i >= (b); --i)
#define allof(a) (a).begin(), (a).end()
#define minit(a, b) memset(a, b, sizeof(a))
#define size_of(a) int((a).size())
#define cauto const auto
// typedef
typedef long long lint;
typedef double Double;
typedef pair<int, int> pii;
template <typename T> using Vec = vector<T>;
template <typename T> using Matrix = Vec<Vec<T>>;
template <typename T> using USet = unordered_set<T>;
template <typename T, class C> using MyUSet = unordered_set<T, C>;
template <typename T, typename F> using UMap = unordered_map<T, F>;
template <typename T, typename F, class C>
using MyUMap = unordered_map<T, F, C>;
// hash
class PiiHash {
public:
  size_t operator()(const pii &p) const { return (p.first << 16) | p.second; }
};
// popcount
inline int POPCNT(int x) { return __builtin_popcount(x); }
inline int POPCNT(lint x) { return __builtin_popcount(x); }
// inf
const int iINF = 1L << 30;
const lint lINF = 1LL << 60;
// eps
const Double EPS = 1e-9;
const Double PI = acos(-1);
// inrange
template <typename T> inline bool in_range(T v, T mi, T mx) {
  return mi <= v && v < mx;
}
template <typename T> inline bool in_range(T x, T y, T W, T H) {
  return in_range(x, 0, W) && in_range(y, 0, H);
}
// neighbor clockwise
const int DX[4] = {0, 1, 0, -1}, DY[4] = {-1, 0, 1, 0};
const int DX_[8] = {0, 1, 1, 1, 0, -1, -1, -1},
          DY_[8] = {-1, -1, 0, 1, 1, 1, 0, -1};
// variable update
template <typename T> inline void modAdd(T &a, T b, T mod) {
  a = (a + b) % mod;
}
template <typename T> inline void minUpdate(T &a, T b) { a = min(a, b); }
template <typename T> inline void maxUpdate(T &a, T b) { a = max(a, b); }
// converter
template <typename F, typename T> inline void convert(F &from, T &to) {
  stringstream ss;
  ss << from;
  ss >> to;
}

int N, L, Q, pow2[22];
lint x[100010], rx[100010];
Vec<Vec<int>> par, rpar;

void preProc(lint *xx, Vec<Vec<int>> &pp) {
  Vec<lint> sum(N + 10, 0);
  for_(i, 0, N + 5) sum[i + 1] = sum[i] + abs(xx[i + 1] - xx[i]);

  for_(i, 0, N) {
    int lb = i + 1, ub = N;

    while (ub - lb > 1) {
      int med = (lb + ub) / 2;
      lint dst = sum[med] - sum[i];
      if (dst > (lint)L)
        ub = med;
      else
        lb = med;
    }

    pp[i][0] = lb;
  }

  for_(k, 0, 20) for_(i, 0, N) {
    if (pp[i][k] < 0)
      pp[i][k] = -1;
    else
      pp[i][k + 1] = pp[pp[i][k]][k];
  }
}

void query(int a, int b, Vec<Vec<int>> &par) {
  // cerr << a << " " << b << endl;
  int ans = 0;

  for_rev(k, 20, 0) {
    if (par[a][k] < 0)
      continue;
    if (b < par[a][k])
      continue;

    a = par[a][k];
    ans += pow2[k];

    if (a == b) {
      printf("%d\n", ans);
      return;
    }

    if (b <= par[a][0]) {
      printf("%d\n", ans + 1);
      return;
    }
  }

  assert(false);
}

int main() {
  cin >> N;
  for_(i, 0, N) {
    cin >> x[i];
    rx[N - i - 1] = x[i];
  }

  cin >> L;
  x[N] = L;
  rx[N] = L;

  par.assign(N + 10, Vec<int>(25, -1));
  preProc(x, par);
  /*
  for_(i,0,N) {
          for_(k,0,20) cerr << par[i][k] << " ";
          cerr << endl;
  }
  */
  rpar.assign(N + 10, Vec<int>(25, -1));
  preProc(rx, rpar);

  pow2[0] = 1;
  for_(i, 1, 22) pow2[i] = pow2[i - 1] * 2;

  cin >> Q;

  for_(q, 0, Q) {
    int a, b;
    scanf("%d %d", &a, &b);
    --a;
    --b;
    if (a < b)
      query(a, b, par);
    else
      query(N - a - 1, N - b - 1, rpar);
  }
}

Fixed submission:
// tsukasa_diary's programing contest code template
#include <bits/stdc++.h>
using namespace std;
#define TSUKASA_DIARY_S_TEMPLATE
// define
#define for_(i, a, b) for (int i = (a); i < (b); ++i)
#define for_rev(i, a, b) for (int i = (a); i >= (b); --i)
#define allof(a) (a).begin(), (a).end()
#define minit(a, b) memset(a, b, sizeof(a))
#define size_of(a) int((a).size())
#define cauto const auto
// typedef
typedef long long lint;
typedef double Double;
typedef pair<int, int> pii;
template <typename T> using Vec = vector<T>;
template <typename T> using Matrix = Vec<Vec<T>>;
template <typename T> using USet = unordered_set<T>;
template <typename T, class C> using MyUSet = unordered_set<T, C>;
template <typename T, typename F> using UMap = unordered_map<T, F>;
template <typename T, typename F, class C>
using MyUMap = unordered_map<T, F, C>;
// hash
class PiiHash {
public:
  size_t operator()(const pii &p) const { return (p.first << 16) | p.second; }
};
// popcount
inline int POPCNT(int x) { return __builtin_popcount(x); }
inline int POPCNT(lint x) { return __builtin_popcount(x); }
// inf
const int iINF = 1L << 30;
const lint lINF = 1LL << 60;
// eps
const Double EPS = 1e-9;
const Double PI = acos(-1);
// inrange
template <typename T> inline bool in_range(T v, T mi, T mx) {
  return mi <= v && v < mx;
}
template <typename T> inline bool in_range(T x, T y, T W, T H) {
  return in_range(x, 0, W) && in_range(y, 0, H);
}
// neighbor clockwise
const int DX[4] = {0, 1, 0, -1}, DY[4] = {-1, 0, 1, 0};
const int DX_[8] = {0, 1, 1, 1, 0, -1, -1, -1},
          DY_[8] = {-1, -1, 0, 1, 1, 1, 0, -1};
// variable update
template <typename T> inline void modAdd(T &a, T b, T mod) {
  a = (a + b) % mod;
}
template <typename T> inline void minUpdate(T &a, T b) { a = min(a, b); }
template <typename T> inline void maxUpdate(T &a, T b) { a = max(a, b); }
// converter
template <typename F, typename T> inline void convert(F &from, T &to) {
  stringstream ss;
  ss << from;
  ss >> to;
}

int N, L, Q, pow2[22];
lint x[100010], rx[100010];
Vec<Vec<int>> par, rpar;

void preProc(lint *xx, Vec<Vec<int>> &pp) {
  Vec<lint> sum(N + 10, 0);
  for_(i, 0, N + 5) sum[i + 1] = sum[i] + abs(xx[i + 1] - xx[i]);

  for_(i, 0, N) {
    int lb = i + 1, ub = N;

    while (ub - lb > 1) {
      int med = (lb + ub) / 2;
      lint dst = sum[med] - sum[i];
      if (dst > (lint)L)
        ub = med;
      else
        lb = med;
    }

    pp[i][0] = lb;
  }

  for_(k, 0, 20) for_(i, 0, N) {
    if (pp[i][k] < 0)
      pp[i][k] = -1;
    else
      pp[i][k + 1] = pp[pp[i][k]][k];
  }
}

void query(int a, int b, Vec<Vec<int>> &par) {
  // cerr << a << " " << b << endl;
  int ans = 0;

  for_rev(k, 20, 0) {
    if (par[a][k] < 0)
      continue;
    if (b < par[a][k])
      continue;

    a = par[a][k];
    ans += pow2[k];

    if (a == b) {
      printf("%d\n", ans);
      return;
    }

    if (b <= par[a][0]) {
      printf("%d\n", ans + 1);
      return;
    }
  }

  // assert(b <= par[a][0]);
  printf("%d\n", ans + 1);
}

int main() {
  cin >> N;
  for_(i, 0, N) {
    cin >> x[i];
    rx[N - i - 1] = x[i];
  }

  cin >> L;
  x[N] = L;
  rx[N] = L;

  par.assign(N + 10, Vec<int>(25, -1));
  preProc(x, par);
  /*
  for_(i,0,N) {
          for_(k,0,20) cerr << par[i][k] << " ";
          cerr << endl;
  }
  */
  rpar.assign(N + 10, Vec<int>(25, -1));
  preProc(rx, rpar);

  pow2[0] = 1;
  for_(i, 1, 22) pow2[i] = pow2[i - 1] * 2;

  cin >> Q;

  for_(q, 0, Q) {
    int a, b;
    scanf("%d %d", &a, &b);
    --a;
    --b;
    if (a < b)
      query(a, b, par);
    else
      query(N - a - 1, N - b - 1, rpar);
  }
}