Problem p02828 (C++)

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

using namespace std;

#define ll long long
#define ld double

#define sz(x) (int)x.size()
#define all(x) x.begin(), x.end()

#define pb emplace_back
#define X first
#define Y second

const int N = 405;
const int S = N * N;

typedef pair<int, int> ii;

const int mod = 998244353;

void add(int &a, int b) {
  a += b;
  if (a >= mod)
    a -= mod;
}
void sub(int &a, int b) {
  a -= b;
  if (a < 0)
    a += mod;
}
int mul(int a, int b) { return 1ll * a * b % mod; }
int Pow(int a, int b) {
  int ans = 1;
  while (b) {
    if (b & 1)
      ans = mul(ans, a);
    a = mul(a, a);
    b >>= 1;
  }
  return ans;
}
int inv(int a, int p) { return a == 1 ? 1 : p - 1ll * p * inv(p % a, a) / a; }

int Fac[N];
int Inv[N];

int Ckn(int n, int k) {
  if (n < k)
    return 0;
  if (k < 0)
    return 0;

  return mul(Fac[n], mul(Inv[k], Inv[n - k]));
}

int a[N];
ii R[N];

int F[S][N];
int G[S][N];

int tot = 0;

int cal(int l, int r, int h) {
  vector<int> vec;

  int p = l;

  for (int i = l; i <= r; ++i)
    if (a[i] == h) {
      if (i > p)
        vec.pb(cal(p, i - 1, h + 1));
      p = i + 1;
    }
  if (r >= p)
    vec.pb(cal(p, r, h + 1));

  vector<int> f(1, 1);
  vector<int> g(1, 1);

  int len = 0;

  for (int x : vec) {
    int L = R[x].Y - R[x].X + 1;

    vector<int> nf(len + L + 1, 0);
    vector<int> ng(len + L + 1, 0);

    for (int i = 0; i <= L; ++i)
      for (int j = 0; j <= len; ++j)
        add(nf[i + j], mul(f[j], F[x][i])), add(ng[i + j], mul(g[j], G[x][i]));

    f.swap(nf);
    g.swap(ng);
    len += L;
  }
  int x = tot;
  int L = r - l + 1;

  vector<int> ng(L + 1);

  for (int i = 0; i <= len; ++i)
    ng[i + L - len] = g[i];

  g.swap(ng);
  f.resize(L + 1);

  for (int i = 0; i <= L; ++i) {
    add(F[x][i], g[i]);
    add(G[x][i], mul(g[i], Pow(2, L - i)));
    add(F[x][i], mul(f[i], Pow(2, L - i) - 1));

    for (int j = 1; j <= i; ++j) {
      int M = mul(Pow(2, L - i), Ckn(i, j));

      add(G[x][i - j], mul(M, g[i]));
      add(F[x][i - j], mul(M, f[i]));
    }
  }
  R[x] = ii(l, r);
  return tot++;
}

int main() {
  ios_base::sync_with_stdio(0);
  cin.tie(0);
  cout.tie(0);

  Fac[0] = Inv[0] = 1;

  for (int i = 1; i < N; ++i)
    Fac[i] = mul(Fac[i - 1], i);
  Inv[N - 1] = inv(Fac[N - 1], mod);
  for (int i = N - 2; i; --i)
    Inv[i] = mul(Inv[i + 1], i + 1);

  int n;
  cin >> n;

  for (int i = 1; i <= n; ++i)
    cin >> a[i];

  cout << F[cal(1, n, 1)][0] << endl;
}

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

using namespace std;

#define ll long long
#define ld double

#define sz(x) (int)x.size()
#define all(x) x.begin(), x.end()

#define pb emplace_back
#define X first
#define Y second

const int N = 405;
const int S = N * N;

typedef pair<int, int> ii;

const int mod = 998244353;

void add(int &a, int b) {
  a += b;
  if (a >= mod)
    a -= mod;
}
void sub(int &a, int b) {
  a -= b;
  if (a < 0)
    a += mod;
}
int mul(int a, int b) { return 1ll * a * b % mod; }
int Pow(int a, int b) {
  int ans = 1;
  while (b) {
    if (b & 1)
      ans = mul(ans, a);
    a = mul(a, a);
    b >>= 1;
  }
  return ans;
}
int inv(int a, int p) { return a == 1 ? 1 : p - 1ll * p * inv(p % a, a) / a; }

int Fac[N];
int Inv[N];

int Ckn(int n, int k) {
  if (n < k)
    return 0;
  if (k < 0)
    return 0;

  return mul(Fac[n], mul(Inv[k], Inv[n - k]));
}

int a[N];
ii R[S];

int F[S][N];
int G[S][N];

int tot = 0;

int cal(int l, int r, int h) {
  vector<int> vec;

  int p = l;

  for (int i = l; i <= r; ++i)
    if (a[i] == h) {
      if (i > p)
        vec.pb(cal(p, i - 1, h + 1));
      p = i + 1;
    }
  if (r >= p)
    vec.pb(cal(p, r, h + 1));

  vector<int> f(1, 1);
  vector<int> g(1, 1);

  int len = 0;

  for (int x : vec) {
    int L = R[x].Y - R[x].X + 1;

    vector<int> nf(len + L + 1, 0);
    vector<int> ng(len + L + 1, 0);

    for (int i = 0; i <= L; ++i)
      for (int j = 0; j <= len; ++j)
        add(nf[i + j], mul(f[j], F[x][i])), add(ng[i + j], mul(g[j], G[x][i]));

    f.swap(nf);
    g.swap(ng);
    len += L;
  }
  int x = tot;
  int L = r - l + 1;

  vector<int> ng(L + 1);

  for (int i = 0; i <= len; ++i)
    ng[i + L - len] = g[i];

  g.swap(ng);
  f.resize(L + 1);

  for (int i = 0; i <= L; ++i) {
    add(F[x][i], g[i]);
    add(G[x][i], mul(g[i], Pow(2, L - i)));
    add(F[x][i], mul(f[i], Pow(2, L - i) - 1));

    for (int j = 1; j <= i; ++j) {
      int M = mul(Pow(2, L - i), Ckn(i, j));

      add(G[x][i - j], mul(M, g[i]));
      add(F[x][i - j], mul(M, f[i]));
    }
  }
  R[x] = ii(l, r);
  return tot++;
}

int main() {
  ios_base::sync_with_stdio(0);
  cin.tie(0);
  cout.tie(0);

  Fac[0] = Inv[0] = 1;

  for (int i = 1; i < N; ++i)
    Fac[i] = mul(Fac[i - 1], i);
  Inv[N - 1] = inv(Fac[N - 1], mod);
  for (int i = N - 2; i; --i)
    Inv[i] = mul(Inv[i + 1], i + 1);

  int n;
  cin >> n;

  for (int i = 1; i <= n; ++i)
    cin >> a[i];

  cout << F[cal(1, n, 1)][0] << endl;
}