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

#include <bits/stdc++.h>
// #include <ext/pb_ds/assoc_container.hpp>
// #include <ext/pb_ds/tree_policy.hpp>

// using namespace __gnu_pbds;
using namespace std;

#define fbo find_by_order
#define ook order_of_key
#define fi first
#define se second
#define long long long
#define mul(a, b) (1LL * a * b) % MOD
#define add(a, b) (a + b) % MOD
#define dec(a, b) (a - b + MOD) % MOD
typedef pair<int, int> ii;
typedef pair<int, ii> iii;
typedef vector<int> vi;
typedef vector<ii> vii;
// typedef tree<int, null_type, less<int>, rb_tree_tag,
// tree_order_statistics_node_update> ordered_set; mt19937_64
// rng(std::chrono::system_clock::now().time_since_epoch().count());

// /mnt/c/Users/vince/Desktop/POST-IOI/

const long MOD = 998244353;
long fac[100003], ifac[100003];
long D[100003];

long pwr(long a, long b) {
  if (b == 0)
    return 1;
  else if (b == 2)
    return mul(a, a);
  else if (b & 1)
    return (pwr(a, b - 1) * a) % MOD;
  else
    return pwr(pwr(a, b / 2), 2);
}

long C(long a, long b) {
  if (b > a)
    return 0;
  return ((fac[a] * ifac[a - b]) % MOD * ifac[b]) % MOD;
}

vector<long> FFT(vector<long> A) {
  int n = A.size();
  if (n == 1)
    return A;

  long Wn = pwr(2, 119 * pwr(2, 23 - int(log2(n) + 1)));
  long W = 1;

  vector<long> Ae, Ao;
  vector<long> Ye, Yo, Y;
  Y.assign(n, 0);
  for (int i = 0; i < n; i += 2)
    Ae.push_back(A[i]);
  for (int i = 1; i < n; i += 2)
    Ao.push_back(A[i]);
  Ye = FFT(Ae);
  Yo = FFT(Ao);
  for (int i = 0; i <= n / 2 - 1; i++) {
    Y[i] = (Ye[i] + (W * Yo[i]) % MOD) % MOD;
    Y[i + n / 2] = dec(Ye[i], mul(W, Yo[i]));
    W = (W * Wn) % MOD;
  }
  return Y;
}

vector<long> IFFT(vector<long> Y) {
  Y = FFT(Y);
  for (int i = 0; i < Y.size(); i++) {
    Y[i] *= pwr(Y.size(), MOD - 2);
    Y[i] %= MOD;
  }
  reverse(Y.begin() + 1, Y.end());
  return Y;
}

// multiplicaton of 2 polinomial in O(n log n) with FFT
//
vector<long> operator*(vector<long> A, vector<long> B) {
  int sz = A.size() + B.size();
  int x = 1;
  while (x < sz)
    x *= 2;
  while (A.size() < x)
    A.push_back(0);
  while (B.size() < x)
    B.push_back(0);

  vector<long> YA = FFT(A);
  vector<long> YB = FFT(B);
  vector<long> YC(YA.size());
  for (int i = 0; i < YA.size(); i++) {
    YC[i] = (YA[i] * YB[i]) % MOD;
  }

  YC = IFFT(YC);
  while (YC.back() == 0)
    YC.pop_back();
  return YC;
}

struct dat {
  vector<long> vec;
  bool operator<(const dat &rhs) const {
    if (vec.size() != rhs.vec.size())
      return vec.size() < rhs.vec.size();
    else
      return vec < rhs.vec;
  }

  dat(vector<long> vec) { this->vec = vec; }
};
int n;
int cnt[100003];

int main() {
  // ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0);
  // freopen("input.in", "r", stdin);

  fac[0] = ifac[0] = 1;
  D[0] = D[2] = 1;
  for (int i = 4; i <= 100000; i++)
    D[i] = mul(D[i - 2], (i - 1));
  for (int i = 1; i <= 100000; i++) {
    fac[i] = (fac[i - 1] * i) % MOD;
    ifac[i] = pwr(fac[i], MOD - 2);
  }

  scanf("%d", &n);
  n += n;
  for (int i = 1; i <= n; i++) {
    int x;
    scanf("%d", &x);
    cnt[x]++;
  }

  multiset<dat> st = {dat({1})};
  for (int i = 1; i <= 100000; i++) {
    if (cnt[i] < 2)
      continue;
    vector<long> vec;
    for (int j = 0; 2 * j <= cnt[i]; j++)
      vec.push_back((C(cnt[i], 2 * j) * D[2 * j]) % MOD);

    st.insert(dat(vec));
  }
  while (st.size() >= 2) {
    vector<long> A = st.begin()->vec;
    st.erase(st.begin());
    vector<long> B = st.begin()->vec;
    st.erase(st.begin());
    st.insert(dat(A * B));
  }

  vector<long> dp = st.begin()->vec;
  long res = 0;
  int tanda = 1;
  for (int i = 0; i < dp.size(); i++) {
    // printf("%d %lld %lld\\n", i, dp[i], D[n-2*i]);
    res = add(res, mul(tanda, mul(dp[i], D[n - 2 * i])));
    tanda *= -1;
  }
  printf("%lld\\n", (res + MOD) % MOD);
}


Error: 0

Fixed submission:

#include <bits/stdc++.h>
// #include <ext/pb_ds/assoc_container.hpp>
// #include <ext/pb_ds/tree_policy.hpp>

// using namespace __gnu_pbds;
using namespace std;

#define fbo find_by_order
#define ook order_of_key
#define fi first
#define se second
#define long long long
#define mul(a, b) (1LL * a * b) % MOD
#define add(a, b) (a + b) % MOD
#define dec(a, b) (a - b + MOD) % MOD
typedef pair<int, int> ii;
typedef pair<int, ii> iii;
typedef vector<int> vi;
typedef vector<ii> vii;
// typedef tree<int, null_type, less<int>, rb_tree_tag,
// tree_order_statistics_node_update> ordered_set; mt19937_64
// rng(std::chrono::system_clock::now().time_since_epoch().count());

// /mnt/c/Users/vince/Desktop/POST-IOI/

const long MOD = 998244353;
long fac[50003], ifac[50003];
long D[100003];

long pwr(long a, long b) {
  if (b == 0)
    return 1;
  else if (b == 2)
    return mul(a, a);
  else if (b & 1)
    return (pwr(a, b - 1) * a) % MOD;
  else
    return pwr(pwr(a, b / 2), 2);
}

long C(long a, long b) {
  if (b > a)
    return 0;
  return ((fac[a] * ifac[a - b]) % MOD * ifac[b]) % MOD;
}

vector<long> FFT(vector<long> A) {
  int n = A.size();
  if (n == 1)
    return A;

  long Wn = pwr(2, 119 * pwr(2, 23 - int(log2(n) + 1)));
  long W = 1;

  vector<long> Ae, Ao;
  vector<long> Ye, Yo, Y;
  Y.assign(n, 0);
  for (int i = 0; i < n; i += 2)
    Ae.push_back(A[i]);
  for (int i = 1; i < n; i += 2)
    Ao.push_back(A[i]);
  Ye = FFT(Ae);
  Yo = FFT(Ao);
  for (int i = 0; i <= n / 2 - 1; i++) {
    Y[i] = (Ye[i] + (W * Yo[i]) % MOD) % MOD;
    Y[i + n / 2] = dec(Ye[i], mul(W, Yo[i]));
    W = (W * Wn) % MOD;
  }
  return Y;
}

vector<long> IFFT(vector<long> Y) {
  Y = FFT(Y);
  for (int i = 0; i < Y.size(); i++) {
    Y[i] *= pwr(Y.size(), MOD - 2);
    Y[i] %= MOD;
  }
  reverse(Y.begin() + 1, Y.end());
  return Y;
}

// multiplicaton of 2 polinomial in O(n log n) with FFT
//
vector<long> operator*(vector<long> A, vector<long> B) {
  int sz = A.size() + B.size();
  int x = 1;
  while (x < sz)
    x *= 2;
  while (A.size() < x)
    A.push_back(0);
  while (B.size() < x)
    B.push_back(0);

  vector<long> YA = FFT(A);
  vector<long> YB = FFT(B);
  vector<long> YC(YA.size());
  for (int i = 0; i < YA.size(); i++) {
    YC[i] = (YA[i] * YB[i]) % MOD;
  }

  YC = IFFT(YC);
  while (YC.back() == 0)
    YC.pop_back();
  return YC;
}

struct dat {
  vector<long> vec;
  bool operator<(const dat &rhs) const {
    if (vec.size() != rhs.vec.size())
      return vec.size() < rhs.vec.size();
    else
      return vec < rhs.vec;
  }

  dat(vector<long> vec) { this->vec = vec; }
};
int n;
int cnt[100003];

int main() {
  // ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0);
  // freopen("input.in", "r", stdin);

  fac[0] = ifac[0] = 1;
  D[0] = D[2] = 1;
  for (int i = 4; i <= 100000; i++)
    D[i] = mul(D[i - 2], (i - 1));
  for (int i = 1; i <= 50000; i++) {
    fac[i] = (fac[i - 1] * i) % MOD;
    ifac[i] = pwr(fac[i], MOD - 2);
  }

  scanf("%d", &n);
  n += n;
  for (int i = 1; i <= n; i++) {
    int x;
    scanf("%d", &x);
    cnt[x]++;
  }

  multiset<dat> st = {dat({1})};
  for (int i = 1; i <= 100000; i++) {
    if (cnt[i] < 2)
      continue;
    vector<long> vec;
    for (int j = 0; 2 * j <= cnt[i]; j++)
      vec.push_back((C(cnt[i], 2 * j) * D[2 * j]) % MOD);

    st.insert(dat(vec));
  }
  while (st.size() >= 2) {
    vector<long> A = st.begin()->vec;
    st.erase(st.begin());
    vector<long> B = st.begin()->vec;
    st.erase(st.begin());
    st.insert(dat(A * B));
  }

  vector<long> dp = st.begin()->vec;
  long res = 0;
  int tanda = 1;
  for (int i = 0; i < dp.size(); i++) {
    // printf("%d %lld %lld\\n", i, dp[i], D[n-2*i]);
    res = add(res, mul(tanda, mul(dp[i], D[n - 2 * i])));
    tanda *= -1;
  }
  printf("%lld\\n", (res + MOD) % MOD);
}