Problem p02539 (C++)

Buggy submission (status: Time Limit Exceeded):
#include <bits/stdc++.h>
#define F first
#define S second
using namespace std;
typedef long long LL;
namespace Math {
const int MOD107 = 1e9 + 7;
const int MOD998 = 998244353;
const int INT_INF = 0x3f3f3f3f;
const LL LL_INF = ((LL)INT_INF << 32) | INT_INF;
struct Value {
  virtual ~Value() = default;
};
template <const int P> struct Mint : Value {
  int v;
  inline int trim(int _v) { return (_v % P + P) % P; }
  Mint(int _v = 0) : v(trim(_v)) {}
  bool operator==(const Mint &m) const { return v == m.v; }
  bool operator!=(const Mint &m) const { return v != m.v; }
  bool operator<(const Mint &m) const { return v < m.v; }
  bool operator<=(const Mint &m) const { return v <= m.v; }
  bool operator>(const Mint &m) const { return v > m.v; }
  bool operator>=(const Mint &m) const { return v >= m.v; }
  friend bool operator==(const int &a, const Mint &m) { return Mint(a) == m.v; }
  friend bool operator!=(const int &a, const Mint &m) { return Mint(a) != m.v; }
  friend bool operator<(const int &a, const Mint &m) { return Mint(a) < m.v; }
  friend bool operator<=(const int &a, const Mint &m) { return Mint(a) <= m.v; }
  friend bool operator>(const int &a, const Mint &m) { return Mint(a) > m.v; }
  friend bool operator>=(const int &a, const Mint &m) { return Mint(a) >= m.v; }
  Mint &operator+=(const Mint &m) {
    v = trim(v + m.v);
    return *this;
  }
  Mint operator+(const Mint &m) const {
    Mint t = *this;
    return t += m;
  }
  friend Mint operator+(const int &a, const Mint &m) { return Mint(a) + m; }
  Mint &operator++() { return *this += 1; }
  Mint operator++(int) {
    Mint t = *this;
    ++*this;
    return t;
  }
  Mint operator-() const { return Mint(-v); }
  Mint &operator-=(const Mint &m) {
    v = trim(v - m.v);
    return *this;
  }
  Mint operator-(const Mint &m) const {
    Mint t = *this;
    return t -= m;
  }
  friend Mint operator-(const int &a, const Mint &m) { return Mint(a) - m; }
  Mint &operator--() { return *this -= 1; }
  Mint operator--(int) {
    Mint t = *this;
    --*this;
    return t;
  }
  Mint &operator*=(const Mint &m) {
    v = trim(1ll * v * m.v % P);
    return *this;
  }
  Mint operator*(const Mint &m) const {
    Mint t = *this;
    return t *= m;
  }
  friend Mint operator*(const int &a, const Mint &m) { return Mint(a) * m; }
  Mint pow(long long n) const {
    Mint m = *this, ans = 1;
    while (n)
      ans *= (n & 1 ? m : 1), m *= m, n >>= 1;
    return ans;
  }
  Mint pow(const Mint &n) const { return pow(n.v); }
  Mint inv() const { return pow(P - 2); }
  Mint &operator/=(const Mint &m) {
    *this = v * m.inv();
    return *this;
  }
  Mint operator/(const Mint &m) {
    Mint t = *this;
    return t /= m;
  }
  friend Mint operator/(const int &a, const Mint &m) { return Mint(a) / m; }
  friend istream &operator>>(istream &in, Mint &m) {
    int v;
    in >> v;
    m = Mint(v);
    return in;
  }
  friend ostream &operator<<(ostream &out, const Mint &m) {
    out << m.v;
    return out;
  }
};
template <typename T> T add(T a, T b) { return a + b; }
template <typename T> T max(T a, T b) { return a < b ? b : a; }
template <typename T> T min(T a, T b) { return a < b ? a : b; }
unordered_map<int, vector<Value *>> fact_mp, inv_mp, fact_inv_mp;
template <const int P> void _build(int n);
template <const int P> Mint<P> fact(int n) {
  assert(0 <= n);
  _build<P>(n);
  auto &_fact = fact_mp[P];
  return *dynamic_cast<Mint<P> *>(_fact[n]);
}
template <const int P> Mint<P> fact_inv(int n) {
  assert(0 <= n);
  _build<P>(n);
  auto &_fact_inv = fact_inv_mp[P];
  return *dynamic_cast<Mint<P> *>(_fact_inv[n]);
}
template <const int P> Mint<P> C(int n, int m) {
  assert(0 <= n && m >= 0 && m <= n);
  _build<P>(n);
  return fact<P>(n) * fact_inv<P>(m) * fact_inv<P>(n - m);
}
template <const int P> Mint<P> inv(int n) {
  assert(0 <= n);
  _build<P>(n);
  auto _inv = inv_mp[P];
  return *dynamic_cast<Mint<P> *>(_inv[n]);
}
template <const int P> void _build(int n) {
  auto &_fact = fact_mp[P];
  auto &_inv = inv_mp[P];
  auto &_fact_inv = fact_inv_mp[P];
  while (_fact.size() <= n) {
    if ((int)_fact.size() <= 1) {
      _fact.push_back(new Mint<P>(1));
      _inv.push_back(new Mint<P>(1));
      _fact_inv.push_back(new Mint<P>(1));
      continue;
    }
    int x = _fact.size();
    _fact.push_back(new Mint<P>(fact<P>(x - 1) * x));
    _inv.push_back(new Mint<P>(-inv<P>(P % x) * Mint<P>(P / x)));
    _fact_inv.push_back(new Mint<P>(fact_inv<P>(x - 1) * inv<P>(x)));
  }
}
} // namespace Math
namespace DS {
template <typename T, T e, T (*F)(T, T)> struct BIT {
  vector<T> data;
  int n;
  BIT(int _n = 0) { init(_n); }
  BIT(vector<T> arr) { init(arr); }
  void init(int _n) {
    n = _n;
    data.assign(n + 1, e);
  }
  void init(vector<T> arr) {
    init(arr.size());
    for (int i = 0; i < arr.size(); i++)
      m(i, arr[i]);
  }
  T q(int R) {
    assert(0 <= R && R <= n);
    T ret = e;
    while (R > 0)
      ret = F(ret, data[R]), R -= R & -R;
    return ret;
  }
  void m(int x, T d) {
    x++;
    while (x <= n)
      data[x] = F(data[x], d), x += x & -x;
  }
  friend ostream &operator<<(ostream &out, BIT &bit) {
    out << "===========================================\n";
    cout << "structure type: BIT, size: " << bit.n << '\n';
    for (int i = 0; i <= bit.n; i++)
      cout << "bit[0, " << i << "): " << bit.q(i) << '\n';
    out << "===========================================\n";
    return out;
  }
  friend istream &operator>>(istream &in, BIT &bit) {
    vector<T> arr(bit.n);
    for (auto &v : arr)
      in >> v;
    bit.init(arr);
    return in;
  }
};
template <typename T, T (*F)(T, T)> struct SparseTable {
  int n, lgn;
  vector<vector<T>> data;
  SparseTable(int _n) {
    vector<T> arr(n = _n);
    init(arr);
  }
  SparseTable(vector<T> arr) { init(arr); }
  void init(vector<T> arr) {
    n = arr.size();
    data.assign(lgn = __lg(n) + 1, vector<T>(n));
    data[0] = arr;
    for (int h = 0; h < lgn - 1; h++) {
      for (int i = 0; i < n; i++) {
        if (i + (1 << h) < n)
          data[h + 1][i] = F(data[h][i], data[h][i + (1 << h)]);
        else
          data[h + 1][i] = data[h][i];
      }
    }
  }
  T q(int L, int R) {
    assert(0 <= L && L < n && 0 < R && R <= n && L < R);
    T ret = data[0][L];
    for (int h = lgn - 1; h >= 0; h--)
      if (L + (1 << h) <= R)
        ret = F(ret, data[h][L]), L += 1 << h;
    return ret;
  }
  friend istream &operator>>(istream &in, SparseTable &st) {
    vector<T> arr(st.n);
    for (auto &v : arr)
      in >> v;
    st.init(arr);
    return in;
  }
  friend ostream &operator<<(ostream &out, SparseTable &st) {
    out << "===========================================\n";
    out << "structure type: SparseTable, size: " << st.n << '\n';
    for (int i = 0; i < st.n; i++)
      for (int j = i + 1; j <= st.n; j++)
        cout << "[" << i << ", " << j << "): " << st.q(i, j) << '\n';
    out << "===========================================\n";
    return out;
  }
};
} // namespace DS
namespace IO {}
namespace Graph {}
namespace Geometry {}
namespace String {}

using namespace Math;
#include <bits/stdc++.h>
#define F first
#define S second
using namespace std;
int fpow(int a, int n, int P) {
  int r = 1;
  while (n) {
    if (n & 1)
      r = 1ll * r * a % P;
    a = 1ll * a * a % P;
    n >>= 1;
  }
  return r;
}
const int P = 998244353, R = 3, MAXN = (1 << 23);
const int MOD = MOD998;
struct Poly : vector<int> {
  int n;
  Poly(int n) : n(n) { this->resize(n); }
  int extend(int x) {
    int N = 1;
    while (N < x)
      N <<= 1;
    return N;
  }
  Poly operator*(const Poly &rhs) {
    Poly a = *this, b = rhs;
    int N = extend(n + rhs.n - 1);
    a.resize(a.n = N);
    a.ntt(1);
    b.resize(b.n = N);
    b.ntt(1);
    for (int i = 0; i < N; i++)
      a[i] = 1ll * a[i] * b[i] % P;
    return a.ntt(-1), a.n = n + rhs.n, a;
  }
  void ntt(int op) {
    static Poly r(MAXN);
    for (int i = 0; i < n; i++) {
      r[i] = (i & 1) * (n >> 1) + (r[i >> 1] >> 1);
      if (r[i] < i)
        std::swap(at(i), at(r[i]));
    }
    for (int m = 2; m <= n; m <<= 1) {
      int k = m >> 1, gn = fpow(R, (P - 1) / m, P);
      for (int i = 0; i < n; i += m) {
        int g = 1;
        for (int j = 0; j < k; j++, g = 1ll * g * gn % P) {
          int tmp = 1ll * at(i + j + k) * g % P;
          at(i + j + k) = (at(i + j) - tmp + P) % P;
          at(i + j) = (at(i + j) + tmp) % P;
        }
      }
    }
    if (op == -1) {
      reverse(begin() + 1, end());
      int inv = fpow(n, P - 2, P);
      for (int i = 0; i < n; i++)
        at(i) = 1ll * at(i) * inv % P;
    }
  }
  bool operator<(const Poly &rhs) const { return n > rhs.n; }
};
typedef pair<int, int> pii;
int main() {
  ios_base::sync_with_stdio(false);
  cin.tie(0);
  int n;
  cin >> n;
  map<int, int> cnt;
  for (int i = 0; i < 2 * n; i++) {
    int v;
    cin >> v;
    cnt[v]++;
  }
  n *= 2;
  priority_queue<Poly> pq;
  for (auto &p : cnt) {
    int k = p.S / 2;
    Poly poly(k + 1);
    for (int i = 0; i <= k; i++) {
      poly[i] = (C<MOD>(p.S, 2 * i) * fact<MOD>(2 * i) * fact_inv<MOD>(i) /
                 Mint<MOD>(2).pow(i))
                    .v;
      //            poly[i] = PP(p.S, 2 * i) * fpow(fpow(2, i, MOD), MOD - 2,
      //            MOD) % MOD * prei[i] % MOD;
    }
    //        cout << p.F << ' ' << p.S << ": ";
    //        for (int i = 0 ; i <= k ; i++)
    //            cout << poly[i] << ' ';
    //        cout << '\n';
    pq.push(poly);
  }
  while (pq.size() > 1) {
    auto a = pq.top();
    pq.pop();
    auto b = pq.top();
    pq.pop();
    pq.push(a * b);
  }
  auto res = pq.top();
  pq.pop();
  //    for (int i = 0 ; i < res.n ; i++)
  //        cout << res[i] << ' ';
  //    cout << '\n';
  Mint<MOD998> ans = 0;
  for (int i = 0; i <= n / 2; i++) {
    if (i % 2 == 0) {
      ans += res[i] * fact<MOD>(n - 2 * i) / Mint<MOD>(2).pow(n / 2 - i) *
             fact_inv<MOD>(n / 2 - i);
    } else {
      ans -= res[i] * fact<MOD>(n - 2 * i) / Mint<MOD>(2).pow(n / 2 - i) *
             fact_inv<MOD>(n / 2 - i);
      //            ans -= res[i] * pre[n - 2 * i] % MOD * fpow(fpow(2, n / 2 -
      //            i, MOD), MOD - 2, MOD) % MOD * prei[n / 2 - i] % MOD; ans +=
      //            MOD; ans %= MOD;
    }
  }
  cout << ans << '\n';
}


Fixed submission:
#include <bits/stdc++.h>
#define F first
#define S second
using namespace std;
typedef long long LL;
namespace Math {
const int MOD107 = 1e9 + 7;
const int MOD998 = 998244353;
const int INT_INF = 0x3f3f3f3f;
const LL LL_INF = ((LL)INT_INF << 32) | INT_INF;
struct Value {
  virtual ~Value() = default;
};
template <const int P> struct Mint : Value {
  int v;
  inline int trim(int _v) { return (_v % P + P) % P; }
  Mint(int _v = 0) : v(trim(_v)) {}
  bool operator==(const Mint &m) const { return v == m.v; }
  bool operator!=(const Mint &m) const { return v != m.v; }
  bool operator<(const Mint &m) const { return v < m.v; }
  bool operator<=(const Mint &m) const { return v <= m.v; }
  bool operator>(const Mint &m) const { return v > m.v; }
  bool operator>=(const Mint &m) const { return v >= m.v; }
  friend bool operator==(const int &a, const Mint &m) { return Mint(a) == m.v; }
  friend bool operator!=(const int &a, const Mint &m) { return Mint(a) != m.v; }
  friend bool operator<(const int &a, const Mint &m) { return Mint(a) < m.v; }
  friend bool operator<=(const int &a, const Mint &m) { return Mint(a) <= m.v; }
  friend bool operator>(const int &a, const Mint &m) { return Mint(a) > m.v; }
  friend bool operator>=(const int &a, const Mint &m) { return Mint(a) >= m.v; }
  Mint &operator+=(const Mint &m) {
    v = trim(v + m.v);
    return *this;
  }
  Mint operator+(const Mint &m) const {
    Mint t = *this;
    return t += m;
  }
  friend Mint operator+(const int &a, const Mint &m) { return Mint(a) + m; }
  Mint &operator++() { return *this += 1; }
  Mint operator++(int) {
    Mint t = *this;
    ++*this;
    return t;
  }
  Mint operator-() const { return Mint(-v); }
  Mint &operator-=(const Mint &m) {
    v = trim(v - m.v);
    return *this;
  }
  Mint operator-(const Mint &m) const {
    Mint t = *this;
    return t -= m;
  }
  friend Mint operator-(const int &a, const Mint &m) { return Mint(a) - m; }
  Mint &operator--() { return *this -= 1; }
  Mint operator--(int) {
    Mint t = *this;
    --*this;
    return t;
  }
  Mint &operator*=(const Mint &m) {
    v = trim(1ll * v * m.v % P);
    return *this;
  }
  Mint operator*(const Mint &m) const {
    Mint t = *this;
    return t *= m;
  }
  friend Mint operator*(const int &a, const Mint &m) { return Mint(a) * m; }
  Mint pow(long long n) const {
    Mint m = *this, ans = 1;
    while (n)
      ans *= (n & 1 ? m : 1), m *= m, n >>= 1;
    return ans;
  }
  Mint pow(const Mint &n) const { return pow(n.v); }
  Mint inv() const { return pow(P - 2); }
  Mint &operator/=(const Mint &m) {
    *this = v * m.inv();
    return *this;
  }
  Mint operator/(const Mint &m) {
    Mint t = *this;
    return t /= m;
  }
  friend Mint operator/(const int &a, const Mint &m) { return Mint(a) / m; }
  friend istream &operator>>(istream &in, Mint &m) {
    int v;
    in >> v;
    m = Mint(v);
    return in;
  }
  friend ostream &operator<<(ostream &out, const Mint &m) {
    out << m.v;
    return out;
  }
};
template <typename T> T add(T a, T b) { return a + b; }
template <typename T> T max(T a, T b) { return a < b ? b : a; }
template <typename T> T min(T a, T b) { return a < b ? a : b; }
unordered_map<int, vector<Value *>> fact_mp, inv_mp, fact_inv_mp;
template <const int P> void _build(int n);
template <const int P> Mint<P> fact(int n) {
  assert(0 <= n);
  _build<P>(n);
  auto &_fact = fact_mp[P];
  return *dynamic_cast<Mint<P> *>(_fact[n]);
}
template <const int P> Mint<P> fact_inv(int n) {
  assert(0 <= n);
  _build<P>(n);
  auto &_fact_inv = fact_inv_mp[P];
  return *dynamic_cast<Mint<P> *>(_fact_inv[n]);
}
template <const int P> Mint<P> C(int n, int m) {
  assert(0 <= n && m >= 0 && m <= n);
  _build<P>(n);
  return fact<P>(n) * fact_inv<P>(m) * fact_inv<P>(n - m);
}
template <const int P> Mint<P> inv(int n) {
  assert(0 <= n);
  _build<P>(n);
  auto &_inv = inv_mp[P];
  return *dynamic_cast<Mint<P> *>(_inv[n]);
}
template <const int P> void _build(int n) {
  auto &_fact = fact_mp[P];
  auto &_inv = inv_mp[P];
  auto &_fact_inv = fact_inv_mp[P];
  while (_fact.size() <= n) {
    if ((int)_fact.size() <= 1) {
      _fact.push_back(new Mint<P>(1));
      _inv.push_back(new Mint<P>(1));
      _fact_inv.push_back(new Mint<P>(1));
      continue;
    }
    int x = _fact.size();
    _fact.push_back(new Mint<P>(fact<P>(x - 1) * x));
    _inv.push_back(new Mint<P>(-inv<P>(P % x) * Mint<P>(P / x)));
    _fact_inv.push_back(new Mint<P>(fact_inv<P>(x - 1) * inv<P>(x)));
  }
}
} // namespace Math
namespace DS {
template <typename T, T e, T (*F)(T, T)> struct BIT {
  vector<T> data;
  int n;
  BIT(int _n = 0) { init(_n); }
  BIT(vector<T> arr) { init(arr); }
  void init(int _n) {
    n = _n;
    data.assign(n + 1, e);
  }
  void init(vector<T> arr) {
    init(arr.size());
    for (int i = 0; i < arr.size(); i++)
      m(i, arr[i]);
  }
  T q(int R) {
    assert(0 <= R && R <= n);
    T ret = e;
    while (R > 0)
      ret = F(ret, data[R]), R -= R & -R;
    return ret;
  }
  void m(int x, T d) {
    x++;
    while (x <= n)
      data[x] = F(data[x], d), x += x & -x;
  }
  friend ostream &operator<<(ostream &out, BIT &bit) {
    out << "===========================================\n";
    cout << "structure type: BIT, size: " << bit.n << '\n';
    for (int i = 0; i <= bit.n; i++)
      cout << "bit[0, " << i << "): " << bit.q(i) << '\n';
    out << "===========================================\n";
    return out;
  }
  friend istream &operator>>(istream &in, BIT &bit) {
    vector<T> arr(bit.n);
    for (auto &v : arr)
      in >> v;
    bit.init(arr);
    return in;
  }
};
template <typename T, T (*F)(T, T)> struct SparseTable {
  int n, lgn;
  vector<vector<T>> data;
  SparseTable(int _n) {
    vector<T> arr(n = _n);
    init(arr);
  }
  SparseTable(vector<T> arr) { init(arr); }
  void init(vector<T> arr) {
    n = arr.size();
    data.assign(lgn = __lg(n) + 1, vector<T>(n));
    data[0] = arr;
    for (int h = 0; h < lgn - 1; h++) {
      for (int i = 0; i < n; i++) {
        if (i + (1 << h) < n)
          data[h + 1][i] = F(data[h][i], data[h][i + (1 << h)]);
        else
          data[h + 1][i] = data[h][i];
      }
    }
  }
  T q(int L, int R) {
    assert(0 <= L && L < n && 0 < R && R <= n && L < R);
    T ret = data[0][L];
    for (int h = lgn - 1; h >= 0; h--)
      if (L + (1 << h) <= R)
        ret = F(ret, data[h][L]), L += 1 << h;
    return ret;
  }
  friend istream &operator>>(istream &in, SparseTable &st) {
    vector<T> arr(st.n);
    for (auto &v : arr)
      in >> v;
    st.init(arr);
    return in;
  }
  friend ostream &operator<<(ostream &out, SparseTable &st) {
    out << "===========================================\n";
    out << "structure type: SparseTable, size: " << st.n << '\n';
    for (int i = 0; i < st.n; i++)
      for (int j = i + 1; j <= st.n; j++)
        cout << "[" << i << ", " << j << "): " << st.q(i, j) << '\n';
    out << "===========================================\n";
    return out;
  }
};
} // namespace DS
namespace IO {}
namespace Graph {}
namespace Geometry {}
namespace String {}

using namespace Math;
#include <bits/stdc++.h>
#define F first
#define S second
using namespace std;
int fpow(int a, int n, int P) {
  int r = 1;
  while (n) {
    if (n & 1)
      r = 1ll * r * a % P;
    a = 1ll * a * a % P;
    n >>= 1;
  }
  return r;
}
const int P = 998244353, R = 3, MAXN = (1 << 23);
const int MOD = MOD998;
struct Poly : vector<int> {
  int n;
  Poly(int n) : n(n) { this->resize(n); }
  int extend(int x) {
    int N = 1;
    while (N < x)
      N <<= 1;
    return N;
  }
  Poly operator*(const Poly &rhs) {
    Poly a = *this, b = rhs;
    int N = extend(n + rhs.n - 1);
    a.resize(a.n = N);
    a.ntt(1);
    b.resize(b.n = N);
    b.ntt(1);
    for (int i = 0; i < N; i++)
      a[i] = 1ll * a[i] * b[i] % P;
    return a.ntt(-1), a.n = n + rhs.n, a;
  }
  void ntt(int op) {
    static Poly r(MAXN);
    for (int i = 0; i < n; i++) {
      r[i] = (i & 1) * (n >> 1) + (r[i >> 1] >> 1);
      if (r[i] < i)
        std::swap(at(i), at(r[i]));
    }
    for (int m = 2; m <= n; m <<= 1) {
      int k = m >> 1, gn = fpow(R, (P - 1) / m, P);
      for (int i = 0; i < n; i += m) {
        int g = 1;
        for (int j = 0; j < k; j++, g = 1ll * g * gn % P) {
          int tmp = 1ll * at(i + j + k) * g % P;
          at(i + j + k) = (at(i + j) - tmp + P) % P;
          at(i + j) = (at(i + j) + tmp) % P;
        }
      }
    }
    if (op == -1) {
      reverse(begin() + 1, end());
      int inv = fpow(n, P - 2, P);
      for (int i = 0; i < n; i++)
        at(i) = 1ll * at(i) * inv % P;
    }
  }
  bool operator<(const Poly &rhs) const { return n > rhs.n; }
};
typedef pair<int, int> pii;
int main() {
  ios_base::sync_with_stdio(false);
  cin.tie(0);
  int n;
  cin >> n;
  map<int, int> cnt;
  for (int i = 0; i < 2 * n; i++) {
    int v;
    cin >> v;
    cnt[v]++;
  }
  n *= 2;
  priority_queue<Poly> pq;
  for (auto &p : cnt) {
    int k = p.S / 2;
    Poly poly(k + 1);
    for (int i = 0; i <= k; i++) {
      poly[i] = (C<MOD>(p.S, 2 * i) * fact<MOD>(2 * i) * fact_inv<MOD>(i) /
                 Mint<MOD>(2).pow(i))
                    .v;
      //            poly[i] = PP(p.S, 2 * i) * fpow(fpow(2, i, MOD), MOD - 2,
      //            MOD) % MOD * prei[i] % MOD;
    }
    //        cout << p.F << ' ' << p.S << ": ";
    //        for (int i = 0 ; i <= k ; i++)
    //            cout << poly[i] << ' ';
    //        cout << '\n';
    pq.push(poly);
  }
  while (pq.size() > 1) {
    auto a = pq.top();
    pq.pop();
    auto b = pq.top();
    pq.pop();
    pq.push(a * b);
  }
  auto res = pq.top();
  pq.pop();
  //    for (int i = 0 ; i < res.n ; i++)
  //        cout << res[i] << ' ';
  //    cout << '\n';
  Mint<MOD998> ans = 0;
  for (int i = 0; i <= n / 2; i++) {
    if (i % 2 == 0) {
      ans += res[i] * fact<MOD>(n - 2 * i) / Mint<MOD>(2).pow(n / 2 - i) *
             fact_inv<MOD>(n / 2 - i);
    } else {
      ans -= res[i] * fact<MOD>(n - 2 * i) / Mint<MOD>(2).pow(n / 2 - i) *
             fact_inv<MOD>(n / 2 - i);
      //            ans -= res[i] * pre[n - 2 * i] % MOD * fpow(fpow(2, n / 2 -
      //            i, MOD), MOD - 2, MOD) % MOD * prei[n / 2 - i] % MOD; ans +=
      //            MOD; ans %= MOD;
    }
  }
  cout << ans << '\n';
}