Problem p03823 (C++)

Buggy submission (status: Runtime Error):
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <iostream>

using std::cin;
using std::cout;
using std::endl;
using std::ios;
using std::min;
using std::sort;
typedef long long ll;
const int N = 100010;
const int MOD = 1e9 + 7;
const ll INFLL = 2e18;
int _w;

void add_mod(int &a, int b) {
  a += b;
  a -= a >= MOD ? MOD : 0;
}

int n, f[N][2];
ll a, b, s[N];

int find(int i, ll v) {
  int low = i + 1, high = n + 1;
  while (low < high) {
    int mid = (low + high) / 2;
    if (s[mid] - s[i] >= v)
      high = mid;
    else
      low = mid + 1;
  }
  return low;
}

namespace RMQ {
ll minv[N * 4], qv;
int ql, qr;
void _init(int o, int L, int R) {
  if (L == R) {
    minv[o] = s[L + 1] - s[L];
  } else {
    int M = (L + R) / 2, lc = o << 1, rc = lc | 1;
    _init(lc, L, M), _init(rc, M + 1, R);
    minv[o] = min(minv[lc], minv[rc]);
  }
}
void init() { _init(1, 1, n - 1); }
void _query(int o, int L, int R) {
  if (L >= ql && R <= qr) {
    qv = min(qv, minv[o]);
  } else {
    int M = (L + R) / 2, lc = o << 1, rc = lc | 1;
    if (ql <= M)
      _query(lc, L, M);
    if (qr > M)
      _query(rc, M + 1, R);
  }
}
ll query(int l, int r) {
  ql = l, qr = r, qv = INFLL;
  _query(1, 1, n - 1);
  return qv;
}
} // namespace RMQ

bool check(int L, int R, ll v) {
  if (L == R)
    return true;
  return RMQ::query(L, R - 1) >= v;
}

int main() {
  ios::sync_with_stdio(false);
  cin >> n >> a >> b;
  for (int i = 1; i <= n; ++i)
    cin >> s[i];
  RMQ::init();
  s[0] = -INFLL, s[n + 1] = INFLL;
  f[1][0] = 1;
  for (int i = 1; i <= n; ++i) {
    if (f[i][0]) {
      if (s[i] - s[i - 1] >= a) {
        add_mod(f[i + 1][0], f[i][0]);
        add_mod(f[i + 1][1], f[i][0]);
      } else {
        int j = find(i - 1, a);
        if (check(i, j - 1, b))
          add_mod(f[j][1], f[i][0]);
      }
    }
    if (f[i][1]) {
      if (s[i] - s[i - 1] >= b) {
        add_mod(f[i + 1][1], f[i][1]);
        add_mod(f[i + 1][0], f[i][1]);
      } else {
        int j = find(i - 1, b);
        if (check(i, j - 1, a))
          add_mod(f[j][0], f[i][1]);
      }
    }
  }
  cout << (f[n + 1][0] + f[n + 1][1]) % MOD << endl;
  return 0;
}


Fixed submission:
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <iostream>

using std::cin;
using std::cout;
using std::endl;
using std::ios;
using std::min;
using std::sort;
typedef long long ll;
const int N = 100010;
const int MOD = 1e9 + 7;
const ll INFLL = 2e18;
int _w;

void add_mod(int &a, int b) {
  a += b;
  a -= a >= MOD ? MOD : 0;
}

int n, f[N][2];
ll a, b, s[N];

int find(int i, ll v) {
  int low = i + 1, high = n + 1;
  while (low < high) {
    int mid = (low + high) / 2;
    if (s[mid] - s[i] >= v)
      high = mid;
    else
      low = mid + 1;
  }
  return low;
}

namespace RMQ {
ll minv[N * 4], qv;
int ql, qr;
void _init(int o, int L, int R) {
  if (L == R) {
    minv[o] = s[L + 1] - s[L];
  } else {
    int M = (L + R) / 2, lc = o << 1, rc = lc | 1;
    _init(lc, L, M), _init(rc, M + 1, R);
    minv[o] = min(minv[lc], minv[rc]);
  }
}
void init() { _init(1, 1, n - 1); }
void _query(int o, int L, int R) {
  if (L >= ql && R <= qr) {
    qv = min(qv, minv[o]);
  } else {
    int M = (L + R) / 2, lc = o << 1, rc = lc | 1;
    if (ql <= M)
      _query(lc, L, M);
    if (qr > M)
      _query(rc, M + 1, R);
  }
}
ll query(int l, int r) {
  ql = l, qr = r, qv = INFLL;
  _query(1, 1, n - 1);
  return qv;
}
} // namespace RMQ

bool check(int L, int R, ll v) {
  if (L == R)
    return true;
  return RMQ::query(L, R - 1) >= v;
}

int main() {
  ios::sync_with_stdio(false);
  cin >> n >> a >> b;
  if (n == 1)
    return puts("2"), 0;
  for (int i = 1; i <= n; ++i)
    cin >> s[i];
  RMQ::init();
  s[0] = -INFLL, s[n + 1] = INFLL;
  f[1][0] = 1;
  for (int i = 1; i <= n; ++i) {
    if (f[i][0]) {
      if (s[i] - s[i - 1] >= a) {
        add_mod(f[i + 1][0], f[i][0]);
        add_mod(f[i + 1][1], f[i][0]);
      } else {
        int j = find(i - 1, a);
        if (check(i, j - 1, b))
          add_mod(f[j][1], f[i][0]);
      }
    }
    if (f[i][1]) {
      if (s[i] - s[i - 1] >= b) {
        add_mod(f[i + 1][1], f[i][1]);
        add_mod(f[i + 1][0], f[i][1]);
      } else {
        int j = find(i - 1, b);
        if (check(i, j - 1, a))
          add_mod(f[j][0], f[i][1]);
      }
    }
  }
  cout << (f[n + 1][0] + f[n + 1][1]) % MOD << endl;
  return 0;
}