Problem p02653 (C++) — buggy submission, verdict: Runtime Error

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int MOD = 1e9 + 7;
struct mi {
  int val;
  explicit operator int() const { return val; }
  mi() { val = 0; }
  mi(const ll &v) {
    val = (-MOD <= v && v <= MOD) ? v : v % MOD;
    if (val < 0)
      val += MOD;
  }
  friend ostream &operator<<(ostream &os, const mi &a) { return os << a.val; }
  friend bool operator==(const mi &a, const mi &b) { return a.val == b.val; }
  friend bool operator!=(const mi &a, const mi &b) { return !(a == b); }
  friend bool operator<(const mi &a, const mi &b) { return a.val < b.val; }
  mi operator-() const { return mi(-val); }
  mi &operator+=(const mi &m) {
    if ((val += m.val) >= MOD)
      val -= MOD;
    return *this;
  }
  mi &operator-=(const mi &m) {
    if ((val -= m.val) < 0)
      val += MOD;
    return *this;
  }
  mi &operator*=(const mi &m) {
    val = (long long)val * m.val % MOD;
    return *this;
  }
  friend mi pow(mi a, long long p) {
    mi ans = 1;
    assert(p >= 0);
    for (; p; p /= 2, a *= a)
      if (p & 1)
        ans *= a;
    return ans;
  }
  friend mi inv(const mi &a) {
    assert(a != 0);
    return pow(a, MOD - 2);
  }
  mi &operator/=(const mi &m) { return (*this) *= inv(m); }
  friend mi operator+(mi a, const mi &b) { return a += b; }
  friend mi operator-(mi a, const mi &b) { return a -= b; }
  friend mi operator*(mi a, const mi &b) { return a *= b; }
  friend mi operator/(mi a, const mi &b) { return a /= b; }
};
const int MAX = 5e3 + 5;
mi dp[MAX][MAX][2];         // have i placed a big 0 stuff
mi prefix[MAX][2 * MAX][2]; // sum for up to i, difference is j, last is last
mi sum[MAX][2];
int a, b;
mi prefix_sum(int l, int r, int diff, int last) {
  if (r < 0)
    return 0;
  if (l > r)
    return 0;
  if (l <= 0)
    return prefix[r][diff][last];
  return prefix[r][diff][last] - prefix[l - 1][diff][last];
}
mi sum_sum(int l, int r, int last) {
  if (r < 0)
    return 0;
  if (l > r)
    return 0;
  if (l <= 0)
    return sum[r][last];
  return sum[r][last] - sum[l - 1][last];
}
int main() {
  ios_base::sync_with_stdio(0);
  cin.tie(0);
  int n;
  cin >> n >> a >> b;
  if (a < b)
    swap(a, b);
  sum[0][1] = 1;
  sum[0][0] = 1;
  prefix[0][MAX][0] = 1;
  prefix[0][MAX][1] = 1;
  for (int i = 1; i <= n; i++) {
    for (int last = 0; last < 2; last++) {
      sum[i][last] = sum[i - 1][last];
    }
    for (int j = 0; j < 2 * MAX; j++) {
      for (int last = 0; last < 2; last++) {
        prefix[i][j][last] = prefix[i - 1][j][last];
      }
    }
    for (int j = 0; j < a; j++) {
      for (int last = 0; last < 2; last++) {
        if (last == 0) {
          dp[i][j][last] =
              prefix_sum(i - min(a - 1, j), i - 1, i - j + MAX, last ^ 1);
        } else {
          if (j == 0) {
            dp[i][j][last] = sum_sum(i - b + 1, i - 1, last ^ 1);
          } else {
            dp[i][j][last] =
                prefix_sum(i - min(a - 1, j), i - b, i - j + MAX, last ^ 1);
          }
        }
        sum[i][last] += dp[i][j][last];
        prefix[i][i - j + MAX][last] += dp[i][j][last];
      }
    }
  }
  mi ans = 1;
  for (int i = 0; i < n; i++)
    ans *= 2;
  mi sub = 0;
  for (int j = 0; j < a; j++) {
    for (int last = 0; last < 2; last++) {
      sub += dp[n][j][last];
    }
  }
  ans -= sub;
  cout << ans.val << '\\n';
}


Error: -11

Fixed submission:

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int MOD = 1e9 + 7;
struct mi {
  int val;
  explicit operator int() const { return val; }
  mi() { val = 0; }
  mi(const ll &v) {
    val = (-MOD <= v && v <= MOD) ? v : v % MOD;
    if (val < 0)
      val += MOD;
  }
  friend ostream &operator<<(ostream &os, const mi &a) { return os << a.val; }
  friend bool operator==(const mi &a, const mi &b) { return a.val == b.val; }
  friend bool operator!=(const mi &a, const mi &b) { return !(a == b); }
  friend bool operator<(const mi &a, const mi &b) { return a.val < b.val; }
  mi operator-() const { return mi(-val); }
  mi &operator+=(const mi &m) {
    if ((val += m.val) >= MOD)
      val -= MOD;
    return *this;
  }
  mi &operator-=(const mi &m) {
    if ((val -= m.val) < 0)
      val += MOD;
    return *this;
  }
  mi &operator*=(const mi &m) {
    val = (long long)val * m.val % MOD;
    return *this;
  }
  friend mi pow(mi a, long long p) {
    mi ans = 1;
    assert(p >= 0);
    for (; p; p /= 2, a *= a)
      if (p & 1)
        ans *= a;
    return ans;
  }
  friend mi inv(const mi &a) {
    assert(a != 0);
    return pow(a, MOD - 2);
  }
  mi &operator/=(const mi &m) { return (*this) *= inv(m); }
  friend mi operator+(mi a, const mi &b) { return a += b; }
  friend mi operator-(mi a, const mi &b) { return a -= b; }
  friend mi operator*(mi a, const mi &b) { return a *= b; }
  friend mi operator/(mi a, const mi &b) { return a /= b; }
};
const int MAX = 5e3 + 5;
mi dp[MAX][MAX][2];         // have i placed a big 0 stuff
mi prefix[MAX][2 * MAX][2]; // sum for up to i, difference is j, last is last
mi sum[MAX][2];
int a, b;
mi prefix_sum(int l, int r, int diff, int last) {
  if (l > r)
    return 0;
  if (l <= 0)
    return prefix[r][diff][last];
  return prefix[r][diff][last] - prefix[l - 1][diff][last];
}
mi sum_sum(int l, int r, int last) {
  if (l <= 0)
    return sum[r][last];
  return sum[r][last] - sum[l - 1][last];
}
int main() {
  ios_base::sync_with_stdio(0);
  cin.tie(0);
  int n;
  cin >> n >> a >> b;
  if (a < b)
    swap(a, b);
  sum[0][1] = 1;
  sum[0][0] = 1;
  prefix[0][MAX][0] = 1;
  prefix[0][MAX][1] = 1;
  for (int i = 1; i <= n; i++) {
    for (int last = 0; last < 2; last++) {
      sum[i][last] = sum[i - 1][last];
    }
    for (int j = 0; j < 2 * MAX; j++) {
      for (int last = 0; last < 2; last++) {
        prefix[i][j][last] = prefix[i - 1][j][last];
      }
    }
    for (int j = 0; j < a; j++) {
      for (int last = 0; last < 2; last++) {
        if (last == 0) {
          dp[i][j][last] =
              prefix_sum(i - min(a - 1, j), i - 1, i - j + MAX, last ^ 1);
        } else {
          if (j == 0) {
            dp[i][j][last] = sum_sum(i - b + 1, i - 1, last ^ 1);
          } else {
            dp[i][j][last] =
                prefix_sum(i - min(a - 1, j), i - b, i - j + MAX, last ^ 1);
          }
        }
        sum[i][last] += dp[i][j][last];
        prefix[i][i - j + MAX][last] += dp[i][j][last];
      }
    }
  }
  mi ans = 1;
  for (int i = 0; i < n; i++)
    ans *= 2;
  mi sub = 0;
  for (int j = 0; j < a; j++) {
    for (int last = 0; last < 2; last++) {
      sub += dp[n][j][last];
    }
  }
  ans -= sub;
  cout << ans.val << '\\n';
}