Problem p03134 (C++)

Buggy submission (status: Runtime Error):
#include <algorithm>
#include <array>
#include <bitset>
#include <cassert>
#include <climits>
#include <cmath>
#include <complex>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <functional>
#include <iostream>
#include <map>
#include <memory>
#include <numeric>
#include <queue>
#include <random>
#include <set>
#include <stack>
#include <unordered_map>
#include <vector>

using namespace std;

typedef long long lint;

const int mod = 998244353, maxn = 2000;

int dp[maxn + 1][maxn + 1];
multiset<int> pos[2];

int solve(int i, int n0, int n1, int n) {
  if (i == 2 * n) {
    return 1;
  }

  int &res = dp[n0][n1];
  if (res != -1)
    return res;

  pair<int, int> range;
  if (i < n) {
    range = {0, i};
  } else {
    range = {0, n - 1};
  }

  res = 0;
  for (int val = 0; val < 2; ++val) {
    auto it = pos[val].lower_bound(range.first);
    if (it != pos[val].end() && *it <= range.second) {
      int this_pos = *it;
      pos[val].erase(it);
      res += solve(i + 1, n0 + (val == 0), n1 + (val == 1), n);
      if (res >= mod)
        res -= mod;
      pos[val].insert(this_pos);
    }
  }

  return res;
}

int main() {
  ios_base::sync_with_stdio(false);
  cin.tie(nullptr);

  string s;
  cin >> s;
  int n = s.size();

  for (int i = 0; i < n; ++i) {
    if (s[i] == '0') {
      pos[0].insert(i);
      pos[0].insert(i);
    } else if (s[i] == '1') {
      pos[0].insert(i);
      pos[1].insert(i);
    } else {
      pos[1].insert(i);
      pos[1].insert(i);
    }
  }

  memset(dp, -1, sizeof(dp));
  int result = solve(0, 0, 0, n);
  printf("%d\n", result);

  return 0;
}


Fixed submission:
#include <algorithm>
#include <array>
#include <bitset>
#include <cassert>
#include <climits>
#include <cmath>
#include <complex>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <functional>
#include <iostream>
#include <map>
#include <memory>
#include <numeric>
#include <queue>
#include <random>
#include <set>
#include <stack>
#include <unordered_map>
#include <vector>

using namespace std;

typedef long long lint;

const int mod = 998244353, maxn = 2000;

int dp[2 * maxn + 1][2 * maxn + 1];
multiset<int> pos[2];

int solve(int i, int n0, int n1, int n) {
  if (i == 2 * n) {
    return 1;
  }

  int &res = dp[n0][n1];
  if (res != -1)
    return res;

  pair<int, int> range;
  if (i < n) {
    range = {0, i};
  } else {
    range = {0, n - 1};
  }

  res = 0;
  for (int val = 0; val < 2; ++val) {
    auto it = pos[val].lower_bound(range.first);
    if (it != pos[val].end() && *it <= range.second) {
      int this_pos = *it;
      pos[val].erase(it);
      res += solve(i + 1, n0 + (val == 0), n1 + (val == 1), n);
      if (res >= mod)
        res -= mod;
      pos[val].insert(this_pos);
    }
  }

  return res;
}

int main() {
  ios_base::sync_with_stdio(false);
  cin.tie(nullptr);

  string s;
  cin >> s;
  int n = s.size();

  for (int i = 0; i < n; ++i) {
    if (s[i] == '0') {
      pos[0].insert(i);
      pos[0].insert(i);
    } else if (s[i] == '1') {
      pos[0].insert(i);
      pos[1].insert(i);
    } else {
      pos[1].insert(i);
      pos[1].insert(i);
    }
  }

  memset(dp, -1, sizeof(dp));
  int result = solve(0, 0, 0, n);
  printf("%d\n", result);

  return 0;
}