Problem p02940 (C++)

Buggy submission (status: Runtime Error):
#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
using namespace std;
using namespace __gnu_pbds;

#define ll long long
#define db long double
#define ii pair<int, int>
#define vi vector<int>
#define fi first
#define se second
#define sz(a) (int)(a).size()
#define all(a) (a).begin(), (a).end()
#define pb push_back
#define mp make_pair
#define FN(i, n) for (int i = 0; i < (int)(n); ++i)
#define FEN(i, n) for (int i = 1; i <= (int)(n); ++i)
#define rep(i, a, b) for (int i = a; i < b; i++)
#define repv(i, a, b) for (int i = b - 1; i >= a; i--)
#define SET(A, val) memset(A, val, sizeof(A))
typedef tree<int, null_type, less<int>, rb_tree_tag,
             tree_order_statistics_node_update>
    ordered_set;
// order_of_key (val): returns the no. of values less than val
// find_by_order (k): returns the kth largest element.(0-based)
#define TRACE
#ifdef TRACE
#define trace(...) __f(#__VA_ARGS__, __VA_ARGS__)
template <typename Arg1> void __f(const char *name, Arg1 &&arg1) {
  cerr << name << " : " << arg1 << std::endl;
}
template <typename Arg1, typename... Args>
void __f(const char *names, Arg1 &&arg1, Args &&...args) {
  const char *comma = strchr(names + 1, ',');
  cerr.write(names, comma - names) << " : " << arg1 << " | ";
  __f(comma + 1, args...);
}
#else
#define trace(...)
#endif
const int mod = 998244353, N = 100005;
int add(int x, int y) {
  x += y;
  if (x >= mod)
    x -= mod;
  if (x < 0)
    x += mod;
  return x;
}
int mult(int x, int y) {
  ll tmp = (ll)x * y;
  if (tmp >= mod)
    tmp %= mod;
  return tmp;
}
// R,G,B,RG,RB,BG
map<vi, int> dp[N];
string s;
int fun(vi v, int ind) {
  if (ind == sz(s))
    return 1;
  if (dp[ind].count(v))
    return dp[ind][v];
  int ans = 0, id;
  if (s[ind] == 'R')
    id = 0;
  else if (s[ind] == 'G')
    id = 1;
  else
    id = 2;
  int nxt1 = (id + 1), nxt2 = (id + 2);
  nxt1 %= 3;
  nxt2 %= 3;
  if (v[5 - id]) // 2 are there
  {
    vi tmp(v);
    tmp[5 - id]--;
    ans = mult(v[5 - id], fun(tmp, ind + 1));
  } else if (!v[nxt1] && !v[nxt2]) // no single is there to join
  {
    vi tmp(v);
    tmp[id]++;
    ans = fun(tmp, ind + 1);
  } else // join with one of the singles
  {
    if (s[ind] == 'R') {
      vi tmp(v);
      // RG
      if (tmp[nxt1]) {
        tmp[nxt1]--;
        tmp[3]++;
        ans = add(ans, mult(v[nxt1], fun(tmp, ind + 1)));
        tmp[nxt1]++;
        tmp[3]--;
      }
      // RB
      if (tmp[nxt2]) {
        tmp[nxt2]--;
        tmp[4]++;
        ans = add(ans, mult(v[nxt2], fun(tmp, ind + 1)));
        tmp[nxt2]++;
        tmp[4]--;
      }
    } else if (s[ind] == 'G') {
      vi tmp(v);
      // GB
      if (tmp[nxt1]) {
        tmp[nxt1]--;
        tmp[5]++;
        ans = add(ans, mult(v[nxt1], fun(tmp, ind + 1)));
        tmp[nxt1]++;
        tmp[5]--;
      }
      // RG
      if (tmp[nxt2]) {
        tmp[nxt2]--;
        tmp[3]++;
        ans = add(ans, mult(v[nxt2], fun(tmp, ind + 1)));
        tmp[nxt2]++;
        tmp[3]--;
      }
    } else {
      vi tmp(v);
      // RB
      if (tmp[nxt1]) {
        tmp[nxt1]--;
        tmp[4]++;
        ans = add(ans, mult(v[nxt1], fun(tmp, ind + 1)));
        tmp[nxt1]++;
        tmp[4]--;
      }
      // BG
      if (tmp[nxt2]) {
        tmp[nxt2]--;
        tmp[5]++;
        ans = add(ans, mult(v[nxt2], fun(tmp, ind + 1)));
        tmp[nxt2]++;
        tmp[5]--;
      }
    }
  }
  return dp[ind][v] = ans;
}
int main() {
  std::ios::sync_with_stdio(false);
  cin.tie(NULL);
  cout.tie(NULL);
  int n;
  cin >> n;
  cin >> s;
  vi v;
  v.resize(6, 0);
  int ans = fun(v, 0);
  rep(i, 1, n + 1) ans = mult(ans, i);
  cout << ans << endl;
  return 0;
}


Fixed submission:
#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
using namespace std;
using namespace __gnu_pbds;

#define ll long long
#define db long double
#define ii pair<int, int>
#define vi vector<int>
#define fi first
#define se second
#define sz(a) (int)(a).size()
#define all(a) (a).begin(), (a).end()
#define pb push_back
#define mp make_pair
#define FN(i, n) for (int i = 0; i < (int)(n); ++i)
#define FEN(i, n) for (int i = 1; i <= (int)(n); ++i)
#define rep(i, a, b) for (int i = a; i < b; i++)
#define repv(i, a, b) for (int i = b - 1; i >= a; i--)
#define SET(A, val) memset(A, val, sizeof(A))
typedef tree<int, null_type, less<int>, rb_tree_tag,
             tree_order_statistics_node_update>
    ordered_set;
// order_of_key (val): returns the no. of values less than val
// find_by_order (k): returns the kth largest element.(0-based)
#define TRACE
#ifdef TRACE
#define trace(...) __f(#__VA_ARGS__, __VA_ARGS__)
template <typename Arg1> void __f(const char *name, Arg1 &&arg1) {
  cerr << name << " : " << arg1 << std::endl;
}
template <typename Arg1, typename... Args>
void __f(const char *names, Arg1 &&arg1, Args &&...args) {
  const char *comma = strchr(names + 1, ',');
  cerr.write(names, comma - names) << " : " << arg1 << " | ";
  __f(comma + 1, args...);
}
#else
#define trace(...)
#endif
const int mod = 998244353, N = 100005;
int add(int x, int y) {
  x += y;
  if (x >= mod)
    x -= mod;
  if (x < 0)
    x += mod;
  return x;
}
int mult(int x, int y) {
  ll tmp = (ll)x * y;
  if (tmp >= mod)
    tmp %= mod;
  return tmp;
}
// R,G,B,RG,RB,BG
map<vi, int> dp[3 * N];
string s;
int fun(vi v, int ind) {
  if (ind == sz(s))
    return 1;
  if (dp[ind].count(v))
    return dp[ind][v];
  int ans = 0, id;
  if (s[ind] == 'R')
    id = 0;
  else if (s[ind] == 'G')
    id = 1;
  else
    id = 2;
  int nxt1 = (id + 1), nxt2 = (id + 2);
  nxt1 %= 3;
  nxt2 %= 3;
  if (v[5 - id]) // 2 are there
  {
    vi tmp(v);
    tmp[5 - id]--;
    ans = mult(v[5 - id], fun(tmp, ind + 1));
  } else if (!v[nxt1] && !v[nxt2]) // no single is there to join
  {
    vi tmp(v);
    tmp[id]++;
    ans = fun(tmp, ind + 1);
  } else // join with one of the singles
  {
    if (s[ind] == 'R') {
      vi tmp(v);
      // RG
      if (tmp[nxt1]) {
        tmp[nxt1]--;
        tmp[3]++;
        ans = add(ans, mult(v[nxt1], fun(tmp, ind + 1)));
        tmp[nxt1]++;
        tmp[3]--;
      }
      // RB
      if (tmp[nxt2]) {
        tmp[nxt2]--;
        tmp[4]++;
        ans = add(ans, mult(v[nxt2], fun(tmp, ind + 1)));
        tmp[nxt2]++;
        tmp[4]--;
      }
    } else if (s[ind] == 'G') {
      vi tmp(v);
      // GB
      if (tmp[nxt1]) {
        tmp[nxt1]--;
        tmp[5]++;
        ans = add(ans, mult(v[nxt1], fun(tmp, ind + 1)));
        tmp[nxt1]++;
        tmp[5]--;
      }
      // RG
      if (tmp[nxt2]) {
        tmp[nxt2]--;
        tmp[3]++;
        ans = add(ans, mult(v[nxt2], fun(tmp, ind + 1)));
        tmp[nxt2]++;
        tmp[3]--;
      }
    } else {
      vi tmp(v);
      // RB
      if (tmp[nxt1]) {
        tmp[nxt1]--;
        tmp[4]++;
        ans = add(ans, mult(v[nxt1], fun(tmp, ind + 1)));
        tmp[nxt1]++;
        tmp[4]--;
      }
      // BG
      if (tmp[nxt2]) {
        tmp[nxt2]--;
        tmp[5]++;
        ans = add(ans, mult(v[nxt2], fun(tmp, ind + 1)));
        tmp[nxt2]++;
        tmp[5]--;
      }
    }
  }
  return dp[ind][v] = ans;
}
int main() {
  std::ios::sync_with_stdio(false);
  cin.tie(NULL);
  cout.tie(NULL);
  int n;
  cin >> n;
  cin >> s;
  vi v;
  v.resize(6, 0);
  int ans = fun(v, 0);
  rep(i, 1, n + 1) ans = mult(ans, i);
  cout << ans << endl;
  return 0;
}