Problem p02653 (C++)

Buggy submission (status: Runtime Error):
#include <bits/stdc++.h>

using namespace std;

mt19937 rng(chrono::high_resolution_clock::now().time_since_epoch().count());
typedef long long ll;
typedef long double ld;

const int N = 5000 + 7;
const int M = (int)1e9 + 7;
int streak[N][2][2], dp_streak[N], dp_0[N];

int add(int a, int b) {
  a += b;
  if (a >= M)
    return a - M;
  if (a < 0)
    return a + M;
  return a;
}

int mul(int a, int b) { return a * (ll)b % M; }

int pw(int a, int b) {
  int r = 1;
  while (b) {
    if (b & 1)
      r = mul(r, a);
    a = mul(a, a);
    b /= 2;
  }
  return r;
}

int dv(int a, int b) { return mul(a, pw(b, M - 2)); }

int n, a, b;
set<string> st;

void bkt(string s) {
  if (st.count(s))
    return;
  st.insert(s);
  for (int i = 0; i + a - 1 < n; i++) {
    string t = s;
    for (int j = i; j <= i + a - 1; j++)
      t[j] = '0';
    bkt(t);
  }
  for (int i = 0; i + b - 1 < n; i++) {
    string t = s;
    for (int j = i; j <= i + b - 1; j++)
      t[j] = '1';
    bkt(t);
  }
}

int dm(int _n, int _a, int _b) {
  n = _n;
  a = _a;
  b = _b;
  st.clear();
  string base;
  for (int i = 1; i <= n; i++)
    base += "0";
  bkt(base);
  return (int)st.size();
}

int sm(int _n, int _a, int _b) {
  n = _n;
  a = _a;
  b = _b;
  if (a > b)
    swap(a, b);
  for (int i = 0; i <= n; i++) {
    for (int f = 0; f <= 1; f++)
      for (int s = 0; s <= 1; s++)
        streak[i][f][s] = 0;
    dp_streak[i] = dp_0[i] = 0;
  }
  for (int l0 = a; l0 <= n; l0++)
    streak[l0][0][0] = 1;
  for (int l1 = 1; l1 <= n; l1++)
    streak[l1][1][1] = 1;
  for (int l = 0; l <= n; l++) {
    for (int f = 0; f <= 1; f++) {
      /// s = 0, now = 1
      for (int l1 = 1; l + l1 <= n; l1++)
        streak[l + l1][f][1] = add(streak[l + l1][f][1], streak[l][f][0]);
      /// s = 1, now = 0
      for (int l0 = a; l0 <= n; l0++)
        streak[l + l0][f][0] = add(streak[l + l0][f][0], streak[l][f][1]);
    }
  }
  /// streak 0 streak 0 streak 0 streak
  /// streak 0 streak 0 streak 0 streak 0
  /// 0 streak 0 streak 0 streak 0 streak
  /// 0 streak 0 streak 0 streak 0 streak 0
  int bad = 0;
  /// stars with streak
  for (int ls = 1; ls < b; ls++)
    dp_streak[ls] = add(streak[ls][0][1], streak[ls][1][1]);
  /// starts with 0
  for (int l0 = 1; l0 < a; l0++)
    dp_0[l0] = add(dp_0[l0], 1);
  for (int l = 1; l <= n; l++) {
    /// streak, 0
    for (int l0 = 1; l + l0 <= n && l0 < a; l0++) {
      dp_0[l + l0] = add(dp_0[l + l0], dp_streak[l]);
    }
    /// 0, streak
    for (int ls = 1; l + ls <= n && ls < b; ls++) {
      if (l + ls == n) {
        dp_streak[l + ls] =
            add(dp_streak[l + ls], mul(dp_0[l], streak[ls][1][0]));
        dp_streak[l + ls] =
            add(dp_streak[l + ls], mul(dp_0[l], streak[ls][1][1]));
      } else {
        dp_streak[l + ls] =
            add(dp_streak[l + ls], mul(dp_0[l], streak[ls][1][1]));
      }
    }
  }
  bad = add(bad, dp_streak[n]);
  bad = add(bad, dp_0[n]);
  return add(pw(2, n), -bad);
}

int main() {
  ios::sync_with_stdio(false);
  cin.tie(0);
  int n, a, b;
  cin >> n >> a >> b;
  cout << sm(n, a, b) << "\n";
  return 0;
}


Fixed submission:
#include <bits/stdc++.h>

using namespace std;

mt19937 rng(chrono::high_resolution_clock::now().time_since_epoch().count());
typedef long long ll;
typedef long double ld;

const int N = 5000 + 7;
const int M = (int)1e9 + 7;
int streak[N][2][2], dp_streak[N], dp_0[N];

int add(int a, int b) {
  a += b;
  if (a >= M)
    return a - M;
  if (a < 0)
    return a + M;
  return a;
}

int mul(int a, int b) { return a * (ll)b % M; }

int pw(int a, int b) {
  int r = 1;
  while (b) {
    if (b & 1)
      r = mul(r, a);
    a = mul(a, a);
    b /= 2;
  }
  return r;
}

int dv(int a, int b) { return mul(a, pw(b, M - 2)); }

int n, a, b;
set<string> st;

void bkt(string s) {
  if (st.count(s))
    return;
  st.insert(s);
  for (int i = 0; i + a - 1 < n; i++) {
    string t = s;
    for (int j = i; j <= i + a - 1; j++)
      t[j] = '0';
    bkt(t);
  }
  for (int i = 0; i + b - 1 < n; i++) {
    string t = s;
    for (int j = i; j <= i + b - 1; j++)
      t[j] = '1';
    bkt(t);
  }
}

int dm(int _n, int _a, int _b) {
  n = _n;
  a = _a;
  b = _b;
  st.clear();
  string base;
  for (int i = 1; i <= n; i++)
    base += "0";
  bkt(base);
  return (int)st.size();
}

int sm(int _n, int _a, int _b) {
  n = _n;
  a = _a;
  b = _b;
  if (a > b)
    swap(a, b);
  for (int i = 0; i <= n; i++) {
    for (int f = 0; f <= 1; f++)
      for (int s = 0; s <= 1; s++)
        streak[i][f][s] = 0;
    dp_streak[i] = dp_0[i] = 0;
  }
  for (int l0 = a; l0 <= n; l0++)
    streak[l0][0][0] = 1;
  for (int l1 = 1; l1 <= n; l1++)
    streak[l1][1][1] = 1;
  for (int l = 0; l <= n; l++) {
    for (int f = 0; f <= 1; f++) {
      /// s = 0, now = 1
      for (int l1 = 1; l + l1 <= n; l1++)
        streak[l + l1][f][1] = add(streak[l + l1][f][1], streak[l][f][0]);
      /// s = 1, now = 0
      for (int l0 = a; l + l0 <= n; l0++)
        streak[l + l0][f][0] = add(streak[l + l0][f][0], streak[l][f][1]);
    }
  }
  /// streak 0 streak 0 streak 0 streak
  /// streak 0 streak 0 streak 0 streak 0
  /// 0 streak 0 streak 0 streak 0 streak
  /// 0 streak 0 streak 0 streak 0 streak 0
  int bad = 0;
  /// stars with streak
  for (int ls = 1; ls < b; ls++)
    dp_streak[ls] = add(streak[ls][0][1], streak[ls][1][1]);
  /// starts with 0
  for (int l0 = 1; l0 < a; l0++)
    dp_0[l0] = add(dp_0[l0], 1);
  for (int l = 1; l <= n; l++) {
    /// streak, 0
    for (int l0 = 1; l + l0 <= n && l0 < a; l0++) {
      dp_0[l + l0] = add(dp_0[l + l0], dp_streak[l]);
    }
    /// 0, streak
    for (int ls = 1; l + ls <= n && ls < b; ls++) {
      if (l + ls == n) {
        dp_streak[l + ls] =
            add(dp_streak[l + ls], mul(dp_0[l], streak[ls][1][0]));
        dp_streak[l + ls] =
            add(dp_streak[l + ls], mul(dp_0[l], streak[ls][1][1]));
      } else {
        dp_streak[l + ls] =
            add(dp_streak[l + ls], mul(dp_0[l], streak[ls][1][1]));
      }
    }
  }
  bad = add(bad, dp_streak[n]);
  bad = add(bad, dp_0[n]);
  return add(pw(2, n), -bad);
}

int main() {
  ios::sync_with_stdio(false);
  cin.tie(0);
  int n, a, b;
  cin >> n >> a >> b;
  cout << sm(n, a, b) << "\n";
  return 0;
}