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

/*

  _|_|                              _|  _|    _|
_|    _|  _|  _|_|  _|_|_|_|        _|  _|  _|
_|    _|  _|_|          _|          _|  _|_|
_|    _|  _|          _|      _|    _|  _|  _|
  _|_|    _|        _|_|_|_|    _|_|    _|    _|

*/
#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <queue>
#include <set>
#include <vector>
// #define ls (rt<<1)
// #define rs (rt<<1|1)
#define vi vector<int>
#define pb push_back
#define mk make_pair
#define pii pair<int, int>
#define rep(i, a, b) for (int i = (a), i##end = (b); i <= i##end; i++)
#define fi first
#define se second
typedef long long ll;
using namespace std;
const int mod = 998244353;
const int maxn = 55000 * 2 * 2;
const int Maxn = 2e6 + 100;
const int len_lim = 55000 * 2;
int ksm(int num, int t) {
  int res = 1;
  for (; t; t >>= 1, num = 1ll * num * num % mod) {
    if (t & 1)
      res = 1ll * res * num % mod;
  }
  return res;
}
struct NTT {
  int wn[2][Maxn], A[Maxn], B[Maxn], rev[Maxn];
  void get_wn(int len) {
    for (int l = 2; l <= (1 << len); l <<= 1) {
      int w1 = ksm(3, (mod - 1) / l), w0 = ksm(3, mod - 1 - (mod - 1) / l);
      wn[1][l >> 1] = wn[0][l >> 1] = 1;
      for (int j = 1; j < (l >> 1); j++) {
        wn[1][(l >> 1) + j] = 1ll * wn[1][(l >> 1) + j - 1] * w1 % mod;
        wn[0][(l >> 1) + j] = 1ll * wn[0][(l >> 1) + j - 1] * w0 % mod;
      }
    }
  }
  void get_rev(int len) {
    rep(i, 1, (1 << len) - 1) rev[i] =
        (rev[i >> 1] >> 1) | ((i & 1) << len - 1);
  }
  void ntt(int len, int *c, int f) {
    rep(i, 0, len) if (rev[i] > i) swap(c[rev[i]], c[i]); //?
    for (int l = 2; l <= len; l <<= 1) {
      for (int i = 0; i + l <= len; i += l) {
        for (int j = i; j < i + (l >> 1); j++) {
          int tmp1 = c[j] % mod,
              tmp2 = 1ll * wn[f][j - i + (l >> 1)] * c[j + (l >> 1)] % mod;
          c[j] = (tmp1 + tmp2) % mod;
          c[j + (l >> 1)] = (tmp1 - tmp2 + mod) % mod;
        }
      }
    }
    if (!f) {
      int inv = ksm(len, mod - 2);
      rep(i, 0, len - 1) c[i] = 1ll * c[i] * inv % mod;
    }
  }
  vi mul(vi a, vi b) {
    int l1 = a.size(), l2 = b.size();
    int len = 1, cnt = 0;
    while (len <= l1 + l2)
      cnt++, len <<= 1;
    get_rev(cnt);
    rep(i, 0, len) A[i] = B[i] = 0;
    rep(i, 0, l1 - 1) A[i] = a[i];
    rep(i, 0, l2 - 1) B[i] = b[i];
    ntt(len, A, 1);
    ntt(len, B, 1);
    rep(i, 0, len - 1) A[i] = 1ll * A[i] * B[i] % mod;
    ntt(len, A, 0);
    vi re;
    rep(i, 0, len - 1) re.pb(A[i]);
    re.resize(min(l1 + l2, len_lim));
    return re;
  }
} t;
int h[maxn], bk[maxn], cnt[maxn];
int frac[maxn];
int C(int m, int n) {
  return 1ll * frac[n] * ksm(1ll * frac[m] * frac[n - m] % mod, mod - 2) % mod;
}
int g(int x) { // x pair combine randomly
  return 1ll * frac[2 * x] * ksm(1ll * frac[x] * ksm(2, x) % mod, mod - 2) %
         mod;
}
vi gen[maxn];
vi solve(int l, int r) {
  if (l == r)
    return gen[l];
  int mid = (l + r) >> 1;
  vi debug = t.mul(solve(l, mid), solve(mid + 1, r));
  return debug;
}
int tmp[maxn];
int main() {
  frac[0] = 1;
  rep(i, 1, maxn - 1) frac[i] = 1ll * i * frac[i - 1] % mod;
  t.get_wn(20);
  ios::sync_with_stdio(0);
  int n;
  cin >> n;
  rep(i, 1, 2 * n) cin >> h[i], bk[i] = h[i];
  sort(bk + 1, bk + 1 + 2 * n);
  int mxid = unique(bk + 1, bk + 1 + 2 * n) - bk - 1; //??
  rep(i, 1, 2 * n) h[i] = lower_bound(bk + 1, bk + 1 + mxid, h[i]) - bk,
                   cnt[h[i]]++;
  rep(i, 1, mxid) {
    rep(j, 0, cnt[i] / 2) { // use j pair
      gen[i].pb(1ll * C(2 * j, cnt[i]) * g(j) % mod);
    }
  }
  vi ans = solve(1, mxid);
  ans.resize(n + 1);
  rep(i, 0, n) { tmp[i] = 1ll * ans[i] * g(n - i) % mod; }
  int out = 0;
  rep(i, 0, n) { out = (out + 1ll * ((i & 1) ? -1 : 1) * tmp[i]) % mod; }
  out = (out + mod) % mod;
  cout << out;
  return 0;
}


Error: WA

Fixed submission:

/*

  _|_|                              _|  _|    _|
_|    _|  _|  _|_|  _|_|_|_|        _|  _|  _|
_|    _|  _|_|          _|          _|  _|_|
_|    _|  _|          _|      _|    _|  _|  _|
  _|_|    _|        _|_|_|_|    _|_|    _|    _|

*/
#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <queue>
#include <set>
#include <vector>
// #define ls (rt<<1)
// #define rs (rt<<1|1)
#define vi vector<int>
#define pb push_back
#define mk make_pair
#define pii pair<int, int>
#define rep(i, a, b) for (int i = (a), i##end = (b); i <= i##end; i++)
#define fi first
#define se second
typedef long long ll;
using namespace std;
const int mod = 998244353;
const int maxn = 55000 * 2 * 2;
const int Maxn = 2e6 + 100;
const int len_lim = 55000 * 2;
int ksm(int num, int t) {
  int res = 1;
  for (; t; t >>= 1, num = 1ll * num * num % mod) {
    if (t & 1)
      res = 1ll * res * num % mod;
  }
  return res;
}
struct NTT {
  int wn[2][Maxn], A[Maxn], B[Maxn], rev[Maxn];
  void get_wn(int len) {
    for (int l = 2; l <= len; l <<= 1) {
      int w1 = ksm(3, (mod - 1) / l), w0 = ksm(3, mod - 1 - (mod - 1) / l);
      wn[1][l >> 1] = wn[0][l >> 1] = 1;
      for (int j = 1; j < (l >> 1); j++) {
        wn[1][(l >> 1) + j] = 1ll * wn[1][(l >> 1) + j - 1] * w1 % mod;
        wn[0][(l >> 1) + j] = 1ll * wn[0][(l >> 1) + j - 1] * w0 % mod;
      }
    }
  }
  void get_rev(int len) {
    rep(i, 1, (1 << len) - 1) rev[i] =
        (rev[i >> 1] >> 1) | ((i & 1) << len - 1);
  }
  void ntt(int len, int *c, int f) {
    rep(i, 0, len) if (rev[i] > i) swap(c[rev[i]], c[i]); //?
    for (int l = 2; l <= len; l <<= 1) {
      for (int i = 0; i + l <= len; i += l) {
        for (int j = i; j < i + (l >> 1); j++) {
          int tmp1 = c[j] % mod,
              tmp2 = 1ll * wn[f][j - i + (l >> 1)] * c[j + (l >> 1)] % mod;
          c[j] = (tmp1 + tmp2) % mod;
          c[j + (l >> 1)] = (tmp1 - tmp2 + mod) % mod;
        }
      }
    }
    if (!f) {
      int inv = ksm(len, mod - 2);
      rep(i, 0, len - 1) c[i] = 1ll * c[i] * inv % mod;
    }
  }
  vi mul(vi a, vi b) {
    int l1 = a.size(), l2 = b.size();
    int len = 1, cnt = 0;
    while (len <= l1 + l2)
      cnt++, len <<= 1;
    get_rev(cnt);
    rep(i, 0, len) A[i] = B[i] = 0;
    rep(i, 0, l1 - 1) A[i] = a[i];
    rep(i, 0, l2 - 1) B[i] = b[i];
    ntt(len, A, 1);
    ntt(len, B, 1);
    rep(i, 0, len - 1) A[i] = 1ll * A[i] * B[i] % mod;
    ntt(len, A, 0);
    vi re;
    rep(i, 0, len - 1) re.pb(A[i]);
    re.resize(min(l1 + l2, len_lim));
    return re;
  }
} t;
int h[maxn], bk[maxn], cnt[maxn];
int frac[maxn];
int C(int m, int n) {
  return 1ll * frac[n] * ksm(1ll * frac[m] * frac[n - m] % mod, mod - 2) % mod;
}
int g(int x) { // x pair combine randomly
  return 1ll * frac[2 * x] * ksm(1ll * frac[x] * ksm(2, x) % mod, mod - 2) %
         mod;
}
vi gen[maxn];
vi solve(int l, int r) {
  if (l == r)
    return gen[l];
  int mid = (l + r) >> 1;
  vi debug = t.mul(solve(l, mid), solve(mid + 1, r));
  return debug;
}
int tmp[maxn];
int main() {
  frac[0] = 1;
  rep(i, 1, maxn - 1) frac[i] = 1ll * i * frac[i - 1] % mod;
  t.get_wn(20);
  ios::sync_with_stdio(0);
  int n;
  cin >> n;
  rep(i, 1, 2 * n) cin >> h[i], bk[i] = h[i];
  sort(bk + 1, bk + 1 + 2 * n);
  int mxid = unique(bk + 1, bk + 1 + 2 * n) - bk - 1; //??
  rep(i, 1, 2 * n) h[i] = lower_bound(bk + 1, bk + 1 + n, h[i]) - bk,
                   cnt[h[i]]++;
  rep(i, 1, mxid) {
    rep(j, 0, cnt[i] / 2) { // use j pair
      gen[i].pb(1ll * C(2 * j, cnt[i]) * g(j) % mod);
    }
  }
  vi ans = solve(1, mxid); // ans.resize(n+1);
  rep(i, 0, n) { tmp[i] = 1ll * ans[i] * g(n - i) % mod; }
  int out = 0;
  rep(i, 0, n) { out = (out + 1ll * ((i & 1) ? -1 : 1) * tmp[i]) % mod; }
  cout << out;
  return 0;
}