Problem p03823 (C++)

Buggy submission (status: Time Limit Exceeded):
#include <bits/stdc++.h>
using namespace std;
#define FOR(i, a, b) for (int i = (a); i < (b); i++)
#define REP(i, a) FOR(i, 0, a)
typedef long long ll;
const int MAX_N = 1e5, MOD = 1e9 + 7;
const ll INF = (1e18) + 4;

int N;
ll A[2];
ll S[MAX_N];

ll memo[MAX_N];
int nex[MAX_N][2];
ll diff[MAX_N];

int st_size;
ll dat[MAX_N * 4];

void init() {
  st_size = 1;
  while (st_size < N - 1)
    st_size <<= 1;
  REP(i, st_size) { dat[i + st_size - 1] = INF; }
  REP(i, N - 1) { dat[i + st_size - 1] = diff[i]; }
  for (int i = st_size - 2; i >= 0; i--) {
    dat[i] = min(dat[i * 2 + 1], dat[i * 2 + 2]);
  }
}

ll query(int s, int t, int k, int a, int b) {
  if (s <= a && b <= t) {
    return dat[k];
  } else if (t <= a || b <= s) {
    return INF;
  } else {
    int m = (a + b) / 2;
    return min(query(s, t, k * 2 + 1, a, m), query(s, t, k * 2 + 2, m, b));
  }
}

int dfs(int n) {
  if (n == N) {
    return 1;
  }
  if (memo[n] != -1) {
    return memo[n];
  }
  int res = 0;
  REP(g, 2) {
    int ne = nex[n][g];
    if (ne != -1) {
      res += dfs(ne);
      res %= MOD;
    }
  }
  return res;
}

int main() {
  scanf("%d", &N);
  REP(i, 2) scanf("%lld", &A[i]);
  REP(i, N) { scanf("%lld", &S[i]); }
  REP(i, N - 1) { diff[i] = S[i + 1] - S[i]; }
  init();
  for (int n = N - 1; n >= 0; n--) {
    REP(g, 2) {
      int lb = lower_bound(S, S + N, S[n] + A[g]) - S;
      if (n + 1 < lb - 1) {
        int mdiff = query(n + 1, lb - 1, 0, 0, st_size);
        if (mdiff < A[(g + 1) % 2]) {
          nex[n][g] = -1;
          continue;
        }
      }
      if (lb == N) {
        nex[n][g] = N;
        continue;
      }
      int s = S[lb];
      if (n + 1 == lb) {
        nex[n][g] = n + 1;
        continue;
      }
      if (S[lb - 1] + A[(g + 1) % 2] <= s) {
        nex[n][g] = lb;
      } else {
        nex[n][g] = nex[lb - 1][(g + 1) % 2];
      }
    }
  }
  memset(memo, -1, sizeof(memo));
  printf("%d\n", dfs(0));
  return 0;
}


Fixed submission:
#include <bits/stdc++.h>
using namespace std;
#define FOR(i, a, b) for (int i = (a); i < (b); i++)
#define REP(i, a) FOR(i, 0, a)
typedef long long ll;
const int MAX_N = 1e5, MOD = 1e9 + 7;
const ll INF = (1e18) + 4;

int N;
ll A[2];
ll S[MAX_N];

ll memo[MAX_N];
int nex[MAX_N][2];
ll diff[MAX_N];

int st_size;
ll dat[MAX_N * 4];

void init() {
  st_size = 1;
  while (st_size < N - 1)
    st_size <<= 1;
  REP(i, st_size) { dat[i + st_size - 1] = INF; }
  REP(i, N - 1) { dat[i + st_size - 1] = diff[i]; }
  for (int i = st_size - 2; i >= 0; i--) {
    dat[i] = min(dat[i * 2 + 1], dat[i * 2 + 2]);
  }
}

ll query(int s, int t, int k, int a, int b) {
  if (s <= a && b <= t) {
    return dat[k];
  } else if (t <= a || b <= s) {
    return INF;
  } else {
    int m = (a + b) / 2;
    return min(query(s, t, k * 2 + 1, a, m), query(s, t, k * 2 + 2, m, b));
  }
}

int dfs(int n) {
  if (n == N) {
    return 1;
  }
  if (memo[n] != -1) {
    return memo[n];
  }
  int res = 0;
  REP(g, 2) {
    int ne = nex[n][g];
    if (ne != -1) {
      res += dfs(ne);
      res %= MOD;
    }
  }
  return memo[n] = res;
}

int main() {
  scanf("%d", &N);
  REP(i, 2) scanf("%lld", &A[i]);
  REP(i, N) { scanf("%lld", &S[i]); }
  REP(i, N - 1) { diff[i] = S[i + 1] - S[i]; }
  init();
  for (int n = N - 1; n >= 0; n--) {
    REP(g, 2) {
      int lb = lower_bound(S, S + N, S[n] + A[g]) - S;
      if (n + 1 < lb - 1) {
        int mdiff = query(n + 1, lb - 1, 0, 0, st_size);
        if (mdiff < A[(g + 1) % 2]) {
          nex[n][g] = -1;
          continue;
        }
      }
      if (lb == N) {
        nex[n][g] = N;
        continue;
      }
      int s = S[lb];
      if (n + 1 == lb) {
        nex[n][g] = n + 1;
        continue;
      }
      if (S[lb - 1] + A[(g + 1) % 2] <= s) {
        nex[n][g] = lb;
      } else {
        nex[n][g] = nex[lb - 1][(g + 1) % 2];
      }
    }
  }
  memset(memo, -1, sizeof(memo));
  printf("%d\n", dfs(0));
  return 0;
}