Problem p03572 (C++)

Buggy submission (status: Runtime Error):
#include <algorithm>
#include <bitset>
#include <climits>
#include <cmath>
#include <complex>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <deque>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <stack>
#include <string>
#include <vector>
#define ll long long
#define __ %= Mod
using namespace std;

const int maxn = 400;
const ll Mod = 1e9 + 7;

int n, N;
int a[maxn], b[maxn];
ll f[maxn][maxn][200];
int as[maxn], bs[maxn];

ll g[maxn][maxn];

int main() {
  scanf("%d", &n);
  N = n / 3;
  for (int i = 1; i <= n; i++)
    scanf("%d", &a[i]), as[a[i]] = i;
  for (int i = 1; i <= n; i++)
    scanf("%d", &b[i]), bs[b[i]] = i;

  // if(a[1]==b[1]) return puts("0"),0;
  f[1][1][0] = 1ll;
  for (int i = 1; i <= n; i++)
    for (int j = 1; j <= n; j++)
      for (int k = 0; k <= N; k++)
        if (f[i][j][k]) {
          ll tmp = f[i][j][k];
          if (bs[a[i]] <= j || as[b[j]] <= i) {
            if (a[i] == b[j]) {
              if (k)
                (f[i + 1][j + 1][k - 1] += tmp * (ll)k % Mod) __;
              continue;
            }
            if (bs[a[i]] <= j)
              (f[i + 1][j][k] += tmp) __;
            else
              (f[i][j + 1][k] += tmp) __;
            continue;
          }
          (f[i + 1][j + 1][k + 1] += tmp) __;
          if (!k)
            continue;
          (f[i + 1][j][k - 1] += tmp * (ll)k % Mod) __;
          (f[i][j + 1][k - 1] += tmp * (ll)k % Mod) __;
          (f[i + 1][j + 1][k - 2] -= tmp * (ll)k % Mod * (k - 1) % Mod) __;
        }
  ll re = 0;
  for (int i = N + 1; i <= n + 1; i++)
    (re += f[i][n + 1][0] + f[n + 1][i][0]) __;
  (re -= f[n + 1][n + 1][0] - Mod) %= Mod;

  g[0][0] = 1ll;
  for (int i = 0; i < n; i++)
    for (int j = 0; j <= i; j++)
      if (g[i][j]) {
        if (i - j < N)
          (g[i + 1][j] += g[i][j]) __;
        if (j < 2 * N && (i - j) * 2 > j)
          (g[i + 1][j + 1] += g[i][j] * (ll)((i - j) * 2 - j) % Mod) __;
      }
  (re *= g[n][2 * N]) __;
  printf("%lld\n", re);

  return 0;
}


Fixed submission:
#include <algorithm>
#include <bitset>
#include <climits>
#include <cmath>
#include <complex>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <deque>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <stack>
#include <string>
#include <vector>
#define ll long long
#define __ %= Mod
using namespace std;

const int maxn = 405;
const ll Mod = 1e9 + 7;

int n, N;
int a[maxn], b[maxn];
ll f[maxn][maxn][200];
int as[maxn], bs[maxn];

ll g[maxn][maxn];

int main() {
  scanf("%d", &n);
  N = n / 3;
  for (int i = 1; i <= n; i++)
    scanf("%d", &a[i]), as[a[i]] = i;
  for (int i = 1; i <= n; i++)
    scanf("%d", &b[i]), bs[b[i]] = i;

  // if(a[1]==b[1]) return puts("0"),0;
  f[1][1][0] = 1ll;
  for (int i = 1; i <= n; i++)
    for (int j = 1; j <= n; j++)
      for (int k = 0; k <= N; k++)
        if (f[i][j][k]) {
          ll tmp = f[i][j][k];
          if (bs[a[i]] <= j || as[b[j]] <= i) {
            if (a[i] == b[j]) {
              if (k)
                (f[i + 1][j + 1][k - 1] += tmp * (ll)k % Mod) __;
              continue;
            }
            if (bs[a[i]] <= j)
              (f[i + 1][j][k] += tmp) __;
            else
              (f[i][j + 1][k] += tmp) __;
            continue;
          }
          (f[i + 1][j + 1][k + 1] += tmp) __;
          if (!k)
            continue;
          (f[i + 1][j][k - 1] += tmp * (ll)k % Mod) __;
          (f[i][j + 1][k - 1] += tmp * (ll)k % Mod) __;
          (f[i + 1][j + 1][k - 2] -= tmp * (ll)k % Mod * (k - 1) % Mod) __;
        }
  ll re = 0;
  for (int i = N + 1; i <= n + 1; i++)
    (re += f[i][n + 1][0] + f[n + 1][i][0]) __;
  (re -= f[n + 1][n + 1][0] - Mod) %= Mod;

  g[0][0] = 1ll;
  for (int i = 0; i < n; i++)
    for (int j = 0; j <= i; j++)
      if (g[i][j]) {
        if (i - j < N)
          (g[i + 1][j] += g[i][j]) __;
        if (j < 2 * N && (i - j) * 2 > j)
          (g[i + 1][j + 1] += g[i][j] * (ll)((i - j) * 2 - j) % Mod) __;
      }
  (re *= g[n][2 * N]) __;
  printf("%lld\n", re);

  return 0;
}