Problem p02539 (C++) — buggy submission, verdict: Runtime Error

#include <bits/stdc++.h>
#define ls ch[x][0]
#define rs ch[x][1]
#define int ll
#define PII pair<int, int>
#define ll long long
#define pb push_back
#define mp make_pair
#define fi first
#define se second
using namespace std;

const int maxn = 400010, mod = 998244353, G = 3;
int n, a[maxn], t[maxn], A[maxn], B[maxn];
vector<int> f[maxn];
int x, len, R[maxn], invG, inv2;
int ksm(int x, int y) {
  int ans = 1;
  while (y) {
    if (y & 1)
      ans = 1ll * ans * x % mod;
    x = 1ll * x * x % mod;
    y >>= 1;
  }
  return ans;
}
void NTT(int *A, int flag) {
  for (int i = 0; i < x; i++)
    if (i < R[i])
      swap(A[i], A[R[i]]);
  for (int mid = 1; mid < x; mid <<= 1) {
    int g;
    if (flag)
      g = ksm(G, (mod - 1) / (mid << 1));
    else
      g = ksm(invG, (mod - 1) / (mid << 1));
    for (int j = 0; j < x; j += (mid << 1)) {
      int sum = 1;
      for (int k = 0; k < mid; k++) {
        int A1 = A[j + k], A2 = 1ll * sum * A[j + k + mid] % mod;
        A[j + k] = (A1 + A2) % mod;
        A[j + k + mid] = ((A1 - A2) % mod + mod) % mod;
        sum = 1ll * sum * g % mod;
      }
    }
  }
  if (!flag) {
    int X = ksm(x, mod - 2);
    for (int i = 0; i < x; i++)
      A[i] = 1ll * A[i] * X % mod;
  }
}
void polymul(int *a, int *b, int n, int m) {
  x = 1;
  len = 0;
  while (n + m >= x)
    x <<= 1, len++;
  for (int i = 0; i < x; i++)
    R[i] = (R[i >> 1] >> 1) | ((i & 1) << len - 1);
  NTT(a, 1);
  NTT(b, 1);
  for (int i = 0; i <= x; i++)
    a[i] = 1ll * a[i] * b[i] % mod;
  NTT(a, 0);
}
priority_queue<PII> que;
int fac[maxn], finv[maxn], inv[maxn];
void init() {
  fac[0] = fac[1] = finv[1] = finv[0] = inv[1] = 1;
  for (int i = 2; i <= 200000; i++) {
    fac[i] = 1ll * fac[i - 1] * i % mod;
    finv[i] = ksm(fac[i], mod - 2);
  }
}
int C(int n, int m) { return 1ll * fac[n] * finv[n - m] % mod * finv[m] % mod; }
signed main() {
  scanf("%d", &n);
  invG = ksm(G, mod - 2);
  init();
  inv2 = (mod + 1) / 2;
  for (int i = 1; i <= 2 * n; i++)
    scanf("%d", &a[i]), t[a[i]]++;
  int id = 0;
  for (int i = 1; i <= 100000; i++)
    if (t[i]) {
      ++id;
      for (int j = 0; j <= t[i] / 2; j++)
        if (j)
          f[id].pb(fac[t[i]] * finv[t[i] - 2 * j] % mod * finv[j] % mod *
                   ksm(ksm(2, j), mod - 2) % mod);
        else
          f[id].pb(1);
      que.push(mp(-t[i] / 2, id));
    }
  while (que.size() != 1) {
    PII nx = que.top();
    que.pop();
    PII ny = que.top();
    que.pop();
    int lenx = -nx.fi, leny = -ny.fi;
    for (int i = 0; i <= lenx; i++)
      A[i] = f[nx.se][i];
    for (int i = 0; i <= leny; i++)
      B[i] = f[ny.se][i];
    polymul(A, B, lenx, leny);
    f[nx.se].clear();
    for (int i = 0; i <= lenx + leny; i++)
      f[nx.se].push_back(A[i]);
    for (int i = 0; i <= x; i++)
      A[i] = B[i] = 0;
    que.push(mp(-(lenx + leny), nx.se));
  }
  PII nx = que.top();
  int ans = 0;
  for (int i = 0; i < f[nx.se].size(); i++) {
    if (i & 1)
      ans = (ans -
             1ll * f[nx.se][i] * fac[2 * n - 2 * i] % mod * finv[n - i] % mod *
                 ksm(ksm(2, n - i), mod - 2) % mod +
             mod) %
            mod;
    else
      ans = (ans + 1ll * f[nx.se][i] * fac[2 * n - 2 * i] % mod * finv[n - i] %
                       mod * ksm(ksm(2, n - i), mod - 2) % mod) %
            mod;
  }
  cout << ans;
  return 0;
}

Error: WA

Fixed submission:

#include <bits/stdc++.h>
#define ls ch[x][0]
#define rs ch[x][1]
#define int ll
#define PII pair<int, int>
#define ll long long
#define pb push_back
#define mp make_pair
#define fi first
#define se second
using namespace std;

const int maxn = 400010, mod = 998244353, G = 3;
int n, a[maxn], t[maxn], A[maxn], B[maxn];
vector<int> f[maxn];
int x, len, R[maxn], invG, inv2;
int ksm(int x, int y) {
  int ans = 1;
  while (y) {
    if (y & 1)
      ans = 1ll * ans * x % mod;
    x = 1ll * x * x % mod;
    y >>= 1;
  }
  return ans;
}
void NTT(int *A, int flag) {
  for (int i = 0; i < x; i++)
    if (i < R[i])
      swap(A[i], A[R[i]]);
  for (int mid = 1; mid < x; mid <<= 1) {
    int g;
    if (flag)
      g = ksm(G, (mod - 1) / (mid << 1));
    else
      g = ksm(invG, (mod - 1) / (mid << 1));
    for (int j = 0; j < x; j += (mid << 1)) {
      int sum = 1;
      for (int k = 0; k < mid; k++) {
        int A1 = A[j + k], A2 = 1ll * sum * A[j + k + mid] % mod;
        A[j + k] = (A1 + A2) % mod;
        A[j + k + mid] = ((A1 - A2) % mod + mod) % mod;
        sum = 1ll * sum * g % mod;
      }
    }
  }
  if (!flag) {
    int X = ksm(x, mod - 2);
    for (int i = 0; i < x; i++)
      A[i] = 1ll * A[i] * X % mod;
  }
}
void polymul(int *a, int *b, int n, int m) {
  x = 1;
  len = 0;
  while (n + m >= x)
    x <<= 1, len++;
  for (int i = 0; i < x; i++)
    R[i] = (R[i >> 1] >> 1) | ((i & 1) << len - 1);
  NTT(a, 1);
  NTT(b, 1);
  for (int i = 0; i <= x; i++)
    a[i] = 1ll * a[i] * b[i] % mod;
  NTT(a, 0);
}
priority_queue<PII> que;
int fac[maxn], finv[maxn], inv[maxn];
void init() {
  fac[0] = fac[1] = finv[1] = finv[0] = inv[1] = 1;
  for (int i = 2; i <= 200000; i++) {
    fac[i] = 1ll * fac[i - 1] * i % mod;
    finv[i] = ksm(fac[i], mod - 2);
  }
}
int C(int n, int m) { return 1ll * fac[n] * finv[n - m] % mod * finv[m] % mod; }
signed main() {
  scanf("%d", &n);
  invG = ksm(G, mod - 2);
  init();
  inv2 = (mod + 1) / 2;
  for (int i = 1; i <= 2 * n; i++)
    scanf("%d", &a[i]), t[a[i]]++;
  int id = 0;
  for (int i = 1; i <= 100000; i++)
    if (t[i]) {
      ++id;
      for (int j = 0; j <= t[i] / 2; j++)
        f[id].pb(C(t[i], j) * C(t[i] - j, j) % mod * fac[j] % mod * inv2 % mod);
      que.push(mp(t[i] / 2, id));
    }
  while (que.size() != 1) {
    PII nx = que.top();
    que.pop();
    PII ny = que.top();
    que.pop();
    int lenx = -nx.fi, leny = -ny.fi;
    for (int i = 0; i <= lenx; i++)
      A[i] = f[nx.se][i];
    for (int i = 0; i <= leny; i++)
      B[i] = f[ny.se][i];
    polymul(A, B, lenx, leny);
    f[nx.se].clear();
    for (int i = 0; i <= lenx + leny; i++)
      f[nx.se].push_back(A[i]);
    for (int i = 0; i <= x; i++)
      A[i] = B[i] = 0;
    que.push(mp(-(lenx + leny), nx.se));
  }
  PII nx = que.top();
  int ans = 0;
  for (int i = 0; i <= nx.fi; i++) {
    if (i & 1)
      ans = (ans -
             1ll * f[nx.fi][i] * C(2 * n - 2 * i, n - i) % mod * fac[n - i] %
                 mod * inv2 % mod +
             mod) %
            mod;
    else
      ans = (ans + 1ll * f[nx.fi][i] * C(2 * n - 2 * i, n - i) % mod *
                       fac[n - i] % mod * inv2 % mod) %
            mod;
  }
  cout << ans;
  return 0;
}