Problem p02828 (C++)

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

using namespace std;

typedef long long LL;
#define N 420
#define M 8200

const LL mod = 998244353;

LL n, ans, a[N], b[N][N], p[N][N], cnt, fa[M], sz[M], sz2[M], sum[M], C[N][N],
    f[M][N], g[M][N], dp[N], pw[N];

void upd(LL &x, LL y) { x = (x + y % mod + mod) % mod; }

int main() {
  scanf("%lld", &n);
  pw[0] = 1;
  for (LL i = 1; i <= n; ++i)
    pw[i] = pw[i - 1] * 2 % mod;
  for (LL i = 1; i <= n; ++i) {
    scanf("%lld", a + i);
    for (LL j = 1; j <= a[i]; ++j)
      b[j][i] = 1;
  }
  for (LL i = 1; i <= n; ++i) {
    for (LL j = 1; j <= n; ++j)
      if (b[i][j]) {
        if (!b[i][j - 1]) {
          p[i][j] = ++cnt;
          fa[cnt] = p[i - 1][j];
        } else
          p[i][j] = p[i][j - 1];
        ++sz[p[i][j]];
        ++sz2[fa[p[i][j]]];
      }
  }
  for (LL i = 1; i <= cnt; ++i) {
    sum[i] = sz[i] - sz2[i];
    f[i][0] = 1;
    g[i][0] = 1;
  }
  for (LL i = 0; i <= n; ++i) {
    C[i][0] = 1;
    for (LL j = 1; j <= i; ++j)
      C[i][j] = (C[i - 1][j - 1] + C[i - 1][j]) % mod;
  }
  for (LL v = cnt; v; --v) {
    memset(dp, 0, sizeof dp);
    for (LL i = 0; i <= sz[v]; ++i) {
      upd(dp[i], g[v][i] * (pw[sz[v] - i] - 1));
      for (LL j = 1; j <= i; ++j)
        upd(dp[i - j], g[v][i] * C[i][j] % mod * pw[sz[v] - i]);
    }
    memcpy(g[v], dp, sizeof g[v]);
    memset(dp, 0, sizeof dp);
    for (LL i = 0; i <= sz[v]; ++i) {
      upd(g[v][sz[v] - i], f[v][i]);
      for (LL j = 0; j <= sz[v] - i; ++j)
        upd(dp[i + j], f[v][i] * C[sz[v] - i][j] % mod * pw[i]);
    }
    memcpy(f[v], dp, sizeof f[v]);
    LL u = fa[v];
    memset(dp, 0, sizeof dp);
    for (LL i = 0; i <= sum[u]; ++i)
      for (LL j = 0; j <= sz[v]; ++j) {
        upd(dp[i + j], f[u][i] * f[v][j]);
      }
    sum[u] += sz[v];
    memcpy(f[u], dp, sizeof f[u]);
    memset(dp, 0, sizeof dp);
    for (LL i = 0; i <= sum[u]; ++i)
      for (LL j = 0; j <= sz[v]; ++j) {
        upd(dp[i + j], g[u][i] * g[v][j]);
      }
    memcpy(g[u], dp, sizeof g[u]);
  }
  printf("%lld\n", g[1][0]);

  return 0;
}


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

using namespace std;

typedef long long LL;
#define N 420
#define M 82000

const LL mod = 998244353;

LL n, ans, a[N], b[N][N], p[N][N], cnt, fa[M], sz[M], sz2[M], sum[M], C[N][N],
    f[M][N], g[M][N], dp[N], pw[N];

void upd(LL &x, LL y) { x = (x + y % mod + mod) % mod; }

int main() {
  scanf("%lld", &n);
  pw[0] = 1;
  for (LL i = 1; i <= n; ++i)
    pw[i] = pw[i - 1] * 2 % mod;
  for (LL i = 1; i <= n; ++i) {
    scanf("%lld", a + i);
    for (LL j = 1; j <= a[i]; ++j)
      b[j][i] = 1;
  }
  for (LL i = 1; i <= n; ++i) {
    for (LL j = 1; j <= n; ++j)
      if (b[i][j]) {
        if (!b[i][j - 1]) {
          p[i][j] = ++cnt;
          fa[cnt] = p[i - 1][j];
        } else
          p[i][j] = p[i][j - 1];
        ++sz[p[i][j]];
        ++sz2[fa[p[i][j]]];
      }
  }
  for (LL i = 1; i <= cnt; ++i) {
    sum[i] = sz[i] - sz2[i];
    f[i][0] = 1;
    g[i][0] = 1;
  }
  for (LL i = 0; i <= n; ++i) {
    C[i][0] = 1;
    for (LL j = 1; j <= i; ++j)
      C[i][j] = (C[i - 1][j - 1] + C[i - 1][j]) % mod;
  }
  for (LL v = cnt; v; --v) {
    memset(dp, 0, sizeof dp);
    for (LL i = 0; i <= sz[v]; ++i) {
      upd(dp[i], g[v][i] * (pw[sz[v] - i] - 1));
      for (LL j = 1; j <= i; ++j)
        upd(dp[i - j], g[v][i] * C[i][j] % mod * pw[sz[v] - i]);
    }
    memcpy(g[v], dp, sizeof g[v]);
    memset(dp, 0, sizeof dp);
    for (LL i = 0; i <= sz[v]; ++i) {
      upd(g[v][sz[v] - i], f[v][i]);
      for (LL j = 0; j <= sz[v] - i; ++j)
        upd(dp[i + j], f[v][i] * C[sz[v] - i][j] % mod * pw[i]);
    }
    memcpy(f[v], dp, sizeof f[v]);
    LL u = fa[v];
    memset(dp, 0, sizeof dp);
    for (LL i = 0; i <= sum[u]; ++i)
      for (LL j = 0; j <= sz[v]; ++j) {
        upd(dp[i + j], f[u][i] * f[v][j]);
      }
    sum[u] += sz[v];
    memcpy(f[u], dp, sizeof f[u]);
    memset(dp, 0, sizeof dp);
    for (LL i = 0; i <= sum[u]; ++i)
      for (LL j = 0; j <= sz[v]; ++j) {
        upd(dp[i + j], g[u][i] * g[v][j]);
      }
    memcpy(g[u], dp, sizeof g[u]);
  }
  printf("%lld\n", g[1][0]);

  return 0;
}