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

/*
 * @Author: Kaizyn
 * @Date: 2020-09-29 17:34:16
 * @LastEditTime: 2020-09-30 20:41:57
 */
#include <bits/stdc++.h>

// #define DEBUG

using namespace std;

const double eps = 1e-7;
const double PI = acos(-1);
typedef pair<int, int> pii;
const int MOD = 998244353;
const int INF = 0x3f3f3f3f;
const int N = 1e5 + 7;

template <typename T, typename H>
inline T qpow(const T &a, const H &p, const int &mo = MOD) {
  long long res = 1, x = a;
  for (H i = p; i; i >>= 1, x = x * x % mo)
    if (i & 1)
      res = res * x % mo;
  return static_cast<T>(res);
}

struct Combination {
  int fac[N], inv[N];
  void init(const int &n) {
    fac[0] = inv[0] = fac[1] = inv[1] = 1;
    for (int i = 2; i <= n; ++i) {
      fac[i] = 1ll * fac[i - 1] * i % MOD;
      inv[i] = 1ll * (MOD - MOD / i) * inv[MOD % i] % MOD;
    }
    for (int i = 2; i <= n; ++i) {
      inv[i] = 1ll * inv[i] * inv[i - 1] % MOD;
    }
  }
  int A(const int &p, const int &q) {
    return p >= q ? 1ll * fac[p] * inv[p - q] % MOD : 0;
  }
  int C(const int &p, const int &q) {
    return p >= q ? 1ll * fac[p] * inv[q] % MOD * inv[p - q] % MOD : 0;
  }
};

// array [0, n)
namespace NTT {
static const int SIZE = (1 << 17) + 3;
const int G = 3;
int len, bit;
int rev[SIZE];
long long f[SIZE], g[SIZE];
template <class T> void ntt(T a[], int flag = 1) {
  for (int i = 0; i < len; ++i)
    if (i < rev[i])
      swap(a[i], a[rev[i]]);
  for (int base = 1; base < len; base <<= 1) {
    long long wn = qpow(G, (MOD - 1) / (base * 2)), w;
    if (flag == -1)
      wn = qpow(wn, MOD - 2);
    for (int i = 0; i < len; i += base * 2) {
      w = 1;
      for (int j = 0; j < base; ++j) {
        long long x = a[i + j], y = w * a[i + j + base] % MOD;
        a[i + j] = (x + y) % MOD;
        a[i + j + base] = (x - y + MOD) % MOD;
        w = w * wn % MOD;
      }
    }
  }
}
template <class T> void work(T a[], const int &n, T b[], const int &m) {
  len = 1;
  bit = 0;
  while (len < n + m)
    len <<= 1, ++bit;
  for (int i = 0; i < n; ++i)
    f[i] = a[i];
  for (int i = n; i < len; ++i)
    f[i] = 0;
  for (int i = 0; i < m; ++i)
    g[i] = b[i];
  for (int i = m; i < len; ++i)
    g[i] = 0;
  for (int i = 0; i < len; ++i)
    rev[i] = (rev[i >> 1] >> 1) | ((i & 1) << (bit - 1));
  ntt(f, 1);
  ntt(g, 1);
  for (int i = 0; i < len; ++i)
    f[i] = f[i] * g[i] % MOD;
  ntt(f, -1);
  long long inv = qpow(len, MOD - 2);
  for (int i = 0; i < n + m - 1; ++i)
    f[i] = f[i] * inv % MOD;
}
} // namespace NTT

int n, m;
int a[N], fff[N]; // fff[i] pair 2i randly
vector<int> ff[N];
Combination comb;

void solve(int l, int r) {
  if (l == r)
    return;
  int m = (l + r) >> 1;
  solve(l, m);
  solve(m + 1, r);
  int ll = ff[l].size(), lr = ff[m + 1].size();
  NTT::work(ff[l].data(), ll, ff[m + 1].data(), lr);
  ff[l].resize(ll + lr - 1);
  for (int i = 0; i < ll + lr - 1; ++i)
    ff[l][i] = NTT::f[i];
}

signed main() {
  ios::sync_with_stdio(false);
  cin.tie(NULL);
  cout.tie(NULL);
  cin >> n;
  for (int i = 1; i <= n * 2; ++i)
    cin >> a[i];
  comb.init(n * 2);
  fff[0] = 1;
  for (int i = 1; i <= n; ++i)
    fff[i] = fff[i - 1] * (i * 2 - 1ll) % MOD;
  sort(a + 1, a + 2 * n + 1);
  for (int i = 1, j; i <= 2 * n; i = j) {
    j = i + 1;
    while (j <= n * 2 && a[j] == a[i])
      ++j;
    ++m;
    for (int k = 0; k * 2 <= j - i; ++k)
      ff[m].emplace_back(1ll * comb.C(j - i, k * 2) * fff[k] % MOD);
  }
  solve(1, m);
#ifdef DEBUG
  for (int &i : ff[1])
    cout << i << " ";
  cout << endl;
#endif
  int res = 0;
  for (int i = 0; i < (int)ff[1].size(); ++i) {
    int val = 1ll * fff[n - i] * ff[1][i] % MOD;
    if (i & 1)
      val = (MOD - val) % MOD;
    (res += val) %= MOD;
  }
  cout << res << endl;
  return 0;
}

Error: 0

Fixed submission:

/*
 * @Author: Kaizyn
 * @Date: 2020-09-29 17:34:16
 * @LastEditTime: 2020-09-30 20:41:30
 */
#include <bits/stdc++.h>

// #define DEBUG

using namespace std;

const double eps = 1e-7;
const double PI = acos(-1);
typedef pair<int, int> pii;
const int MOD = 998244353;
const int INF = 0x3f3f3f3f;
const int N = 1e3 + 7;

template <typename T, typename H>
inline T qpow(const T &a, const H &p, const int &mo = MOD) {
  long long res = 1, x = a;
  for (H i = p; i; i >>= 1, x = x * x % mo)
    if (i & 1)
      res = res * x % mo;
  return static_cast<T>(res);
}

struct Combination {
  int fac[N], inv[N];
  void init(const int &n) {
    fac[0] = inv[0] = fac[1] = inv[1] = 1;
    for (int i = 2; i <= n; ++i) {
      fac[i] = 1ll * fac[i - 1] * i % MOD;
      inv[i] = 1ll * (MOD - MOD / i) * inv[MOD % i] % MOD;
    }
    for (int i = 2; i <= n; ++i) {
      inv[i] = 1ll * inv[i] * inv[i - 1] % MOD;
    }
  }
  int A(const int &p, const int &q) {
    return p >= q ? 1ll * fac[p] * inv[p - q] % MOD : 0;
  }
  int C(const int &p, const int &q) {
    return p >= q ? 1ll * fac[p] * inv[q] % MOD * inv[p - q] % MOD : 0;
  }
};

// array [0, n)
namespace NTT {
static const int SIZE = (1 << 17) + 3;
const int G = 3;
int len, bit;
int rev[SIZE];
long long f[SIZE], g[SIZE];
template <class T> void ntt(T a[], int flag = 1) {
  for (int i = 0; i < len; ++i)
    if (i < rev[i])
      swap(a[i], a[rev[i]]);
  for (int base = 1; base < len; base <<= 1) {
    long long wn = qpow(G, (MOD - 1) / (base * 2)), w;
    if (flag == -1)
      wn = qpow(wn, MOD - 2);
    for (int i = 0; i < len; i += base * 2) {
      w = 1;
      for (int j = 0; j < base; ++j) {
        long long x = a[i + j], y = w * a[i + j + base] % MOD;
        a[i + j] = (x + y) % MOD;
        a[i + j + base] = (x - y + MOD) % MOD;
        w = w * wn % MOD;
      }
    }
  }
}
template <class T> void work(T a[], const int &n, T b[], const int &m) {
  len = 1;
  bit = 0;
  while (len < n + m)
    len <<= 1, ++bit;
  for (int i = 0; i < n; ++i)
    f[i] = a[i];
  for (int i = n; i < len; ++i)
    f[i] = 0;
  for (int i = 0; i < m; ++i)
    g[i] = b[i];
  for (int i = m; i < len; ++i)
    g[i] = 0;
  for (int i = 0; i < len; ++i)
    rev[i] = (rev[i >> 1] >> 1) | ((i & 1) << (bit - 1));
  ntt(f, 1);
  ntt(g, 1);
  for (int i = 0; i < len; ++i)
    f[i] = f[i] * g[i] % MOD;
  ntt(f, -1);
  long long inv = qpow(len, MOD - 2);
  for (int i = 0; i < n + m - 1; ++i)
    f[i] = f[i] * inv % MOD;
}
} // namespace NTT

int n, m;
int a[N], fff[N]; // fff[i] pair 2i randly
vector<int> ff[N];
Combination comb;

void solve(int l, int r) {
  if (l == r)
    return;
  int m = (l + r) >> 1;
  solve(l, m);
  solve(m + 1, r);
  int ll = ff[l].size(), lr = ff[m + 1].size();
  NTT::work(ff[l].data(), ll, ff[m + 1].data(), lr);
  ff[l].resize(ll + lr - 1);
  for (int i = 0; i < ll + lr - 1; ++i)
    ff[l][i] = NTT::f[i];
}

signed main() {
  ios::sync_with_stdio(false);
  cin.tie(NULL);
  cout.tie(NULL);
  cin >> n;
  for (int i = 1; i <= n * 2; ++i)
    cin >> a[i];
  comb.init(n * 2);
  fff[0] = 1;
  for (int i = 1; i <= n; ++i)
    fff[i] = fff[i - 1] * (i * 2 - 1ll) % MOD;
  sort(a + 1, a + 2 * n + 1);
  for (int i = 1, j; i <= 2 * n; i = j) {
    j = i + 1;
    while (j <= n * 2 && a[j] == a[i])
      ++j;
    ++m;
    for (int k = 0; k * 2 <= j - i; ++k)
      ff[m].emplace_back(1ll * comb.C(j - i, k * 2) * fff[k] % MOD);
  }
  solve(1, m);
#ifdef DEBUG
  for (int &i : ff[1])
    cout << i << " ";
  cout << endl;
#endif
  int res = 0;
  for (int i = 0; i < (int)ff[1].size(); ++i) {
    int val = 1ll * fff[n - i] * ff[1][i] % MOD;
    if (i & 1)
      val = (MOD - val) % MOD;
    (res += val) %= MOD;
  }
  cout << res << endl;
  return 0;
}