Problem p03134 (C++)

Buggy submission (status: Runtime Error):
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <iostream>
#define ll long long
using namespace std;
template <class T> inline void read(T &x) {
  x = 0;
  char c = getchar();
  int f = 1;
  while (!isdigit(c)) {
    if (c == '-')
      f = -1;
    c = getchar();
  }
  while (isdigit(c))
    x = x * 10 - '0' + c, c = getchar();
  x *= f;
}
const int N = 2010, mod = 998244353;
ll Pow(ll x, ll y) {
  ll res = 1;
  while (y) {
    if (y & 1)
      res = res * x % mod;
    x = x * x % mod, y >>= 1;
  }
  return res;
}
char str[N];
int sum[N][2], n;
ll dp[N][N], frac[N], inv[N];
int main() {
  scanf("%s", str + 1);
  n = strlen(str + 1);
  for (int i = 1; i <= n; ++i) {
    sum[i][0] = sum[i - 1][0] + (str[i] - '0');
    sum[i][1] = sum[i - 1][1] + 2 - (str[i] - '0');
  }
  frac[0] = 1;
  for (int i = 1; i <= n; ++i)
    frac[i] = frac[i - 1] * i % mod;
  inv[n] = Pow(frac[n], mod - 2);
  for (int i = n - 1; i >= 0; --i)
    inv[i] = inv[i + 1] * (i + 1) % mod;

  dp[0][0] = 1;
  for (int i = 0; i < n; ++i)
    for (int j = 0; j <= i; ++j)
      if (dp[i][j]) {
        if (sum[i + 1][0] >= j + 1)
          dp[i + 1][j + 1] = (dp[i + 1][j + 1] + dp[i][j]) % mod;
        if (sum[i + 1][1] >= i + 1 - j)
          dp[i + 1][j] = (dp[i + 1][j] + dp[i][j]) % mod;
      }
  //	for(int j=0;j<=n;++j) printf("%0lld\n",dp[n][j]);
  ll ans = 0;
  for (int i = 0; i <= n; ++i)
    ans = (ans + dp[n][i] * inv[sum[n][0] - i] % mod *
                     inv[sum[n][1] - (n - i)] % mod);
  ans = ans * frac[n] % mod;
  printf("%lld", ans);
  return 0;
}

Fixed submission:
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <iostream>
#define ll long long
using namespace std;
template <class T> inline void read(T &x) {
  x = 0;
  char c = getchar();
  int f = 1;
  while (!isdigit(c)) {
    if (c == '-')
      f = -1;
    c = getchar();
  }
  while (isdigit(c))
    x = x * 10 - '0' + c, c = getchar();
  x *= f;
}
const int N = 2010, mod = 998244353;
ll Pow(ll x, ll y) {
  ll res = 1;
  while (y) {
    if (y & 1)
      res = res * x % mod;
    x = x * x % mod, y >>= 1;
  }
  return res;
}
char str[N];
int sum[N][2], n;
ll dp[N][N], frac[N], inv[N];
int main() {
  scanf("%s", str + 1);
  n = strlen(str + 1);
  for (int i = 1; i <= n; ++i) {
    sum[i][0] = sum[i - 1][0] + (str[i] - '0');
    sum[i][1] = sum[i - 1][1] + 2 - (str[i] - '0');
  }
  frac[0] = 1;
  for (int i = 1; i <= n; ++i)
    frac[i] = frac[i - 1] * i % mod;
  inv[n] = Pow(frac[n], mod - 2);
  for (int i = n - 1; i >= 0; --i)
    inv[i] = inv[i + 1] * (i + 1) % mod;

  dp[0][0] = 1;
  for (int i = 0; i < n; ++i)
    for (int j = 0; j <= i; ++j)
      if (dp[i][j]) {
        if (sum[i + 1][0] >= j + 1)
          dp[i + 1][j + 1] = (dp[i + 1][j + 1] + dp[i][j]) % mod;
        if (sum[i + 1][1] >= i + 1 - j)
          dp[i + 1][j] = (dp[i + 1][j] + dp[i][j]) % mod;
      }
  //	for(int j=0;j<=n;++j) printf("%0lld\n",dp[n][j]);
  ll ans = 0;
  for (int i = 0; i <= n; ++i)
    if (sum[n][0] >= i && sum[n][1] >= (n - i))
      ans = (ans + dp[n][i] * inv[sum[n][0] - i] % mod *
                       inv[sum[n][1] - (n - i)] % mod) %
            mod;
  ans = ans * frac[n] % mod;
  printf("%lld", ans);
  return 0;
}