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

#include <bits/stdc++.h>
using namespace std;
#define FOR(i, a, b) for (int i = (a); i < (b); ++i)
#define REP(i, n) FOR(i, 0, n)
#define ALL(v) begin(v), end(v)
#define fi first
#define se second
template <typename A, typename B> inline bool chmax(A &a, B b) {
  if (a < b) {
    a = b;
    return 1;
  }
  return 0;
}
template <typename A, typename B> inline bool chmin(A &a, B b) {
  if (a > b) {
    a = b;
    return 1;
  }
  return 0;
}
using ll = long long;
using pii = pair<int, int>;
constexpr ll INF = 1ll << 30;
constexpr ll longINF = 1ll << 60;
constexpr ll MOD = 1000000007;
constexpr bool debug = 0;
//---------------------------------//

struct UnionFind {
public:
  using size_type = std::size_t;

  UnionFind(size_type n) : n(n), size_(n, 1) {
    par.resize(n);
    std::iota(par.begin(), par.end(), 0);
  }

  size_type size(size_type x) { return size_[find(x)]; }

  size_type find(size_type x) {
    assert(x < n);
    while (par[x] != x) {
      par[x] = par[par[x]];
      x = par[x];
    }
    return x;
  }

  void merge(size_type x, size_type y) {
    x = find(x);
    y = find(y);
    if (x == y)
      return;
    if (size(x) > size(y))
      std::swap(x, y);
    par[x] = y;
    size_[y] += size_[x];
  }

  bool issame(size_type x, size_type y) { return find(x) == find(y); }

private:
  size_type n;
  std::vector<size_type> size_, par;
};

template <int M> struct ModInt {
public:
  using value_type = long long;

  ModInt(value_type val = 0) : val(val < 0 ? (M - (-val % M)) % M : val % M) {}

  explicit operator bool() const noexcept { return val; }
  bool operator==(const ModInt &rhs) const noexcept { return val == rhs.val; }
  bool operator!=(const ModInt &rhs) const noexcept { return !(*this == rhs); }
  ModInt operator+() const noexcept { return ModInt(*this); }
  ModInt operator-() const noexcept { return ModInt(0) -= *this; }
  ModInt operator+(const ModInt &rhs) const noexcept {
    return ModInt(*this) += rhs;
  }
  ModInt operator-(const ModInt &rhs) const noexcept {
    return ModInt(*this) -= rhs;
  }
  ModInt operator*(const ModInt &rhs) const noexcept {
    return ModInt(*this) *= rhs;
  }
  ModInt operator/(const ModInt &rhs) const noexcept {
    return ModInt(*this) /= rhs;
  }

  ModInt &operator+=(const ModInt &rhs) noexcept {
    val += rhs.val;
    if (val >= M)
      val -= M;
    return *this;
  }
  ModInt &operator-=(const ModInt &rhs) noexcept {
    if (val < rhs.val)
      val += M;
    val -= rhs.val;
    return *this;
  }
  ModInt &operator*=(const ModInt &rhs) noexcept {
    val = val * rhs.val % M;
    return *this;
  }
  ModInt &operator/=(const ModInt &rhs) noexcept {
    *this *= rhs.inverse();
    return *this;
  }

  ModInt pow(value_type n) const {
    ModInt res = 1, x = val;
    if (n < 0) {
      x = x.inverse();
      n = -n;
    }
    while (n) {
      if (n & 1)
        res *= x;
      x *= x;
      n >>= 1;
    }
    return res;
  }

  ModInt inverse() const {
    long long a = val, a1 = 1, a2 = 0, b = M, b1 = 0, b2 = 1;
    while (b > 0) {
      value_type q = a / b, r = a % b;
      value_type nb1 = a1 - q * b1, nb2 = a2 - q * b2;
      a = b;
      b = r;
      a1 = b1;
      b1 = nb1;
      a2 = b2;
      b2 = nb2;
    }
    assert(a == 1);
    return a1;
  }

  const value_type &get() const noexcept { return val; }
  static decltype(M) get_mod() noexcept { return M; }

  friend std::ostream &operator<<(std::ostream &os, const ModInt &rhs) {
    return os << rhs.val;
  }
  friend std::istream &operator>>(std::istream &is, ModInt &rhs) {
    value_type x;
    is >> x;
    rhs = ModInt(x);
    return is;
  }

private:
  value_type val;
};
using mint = ModInt<MOD>;

template <typename T> struct Combination {
public:
  using size_type = std::size_t;

  Combination(size_type sz = 1) : _fact(1, 1), _finv(1, 1), _inv(1, 1) {
    build(sz);
  }

  T fact(size_type k) {
    if (k >= T::get_mod())
      return 0;
    build(k);
    return _fact[k];
  }
  T finv(size_type k) {
    assert(k < T::get_mod());
    build(k);
    return _finv[k];
  }
  T inv(size_type k) {
    assert(k > 0 && k < T::get_mod());
    build(k);
    return _inv[k];
  }

  T operator()(int n, int r) { return c(n, r); }
  T c(int n, int r) {
    if (r < 0 || n < r)
      return 0;
    return fact(n) * finv(r) * finv(n - r);
  }

private:
  std::vector<T> _fact, _finv, _inv;
  static constexpr size_type MAX_LIMIT = 50000000;

  void build(size_type k) {
    if (_fact.size() > k)
      return;
    assert(k < MAX_LIMIT);
    size_type sz = std::min({MAX_LIMIT, static_cast<size_type>(T::get_mod()),
                             std::max(_fact.size() * 2, k + 1)});
    size_type presz = _fact.size();
    _fact.resize(sz);
    _finv.resize(sz);
    _inv.resize(sz);

    for (size_type i = presz; i < sz; ++i)
      _fact[i] = _fact[i - 1] * i;
    _finv[sz - 1] = T(_fact[sz - 1]).inverse();
    for (size_type i = sz - 1; i > presz; --i) {
      _finv[i - 1] = _finv[i] * i;
      _inv[i] = _fact[i - 1] * _finv[i];
    }
    _inv[presz] = _fact[presz - 1] * _finv[presz];
  }
};
using Comb = Combination<mint>;
Comb comb;

int main() {
  int N;
  cin >> N;
  vector<int> P(N);
  REP(i, N) {
    scanf("%d", &P[i]);
    if (P[i] > 0)
      --P[i];
  }

  UnionFind uf(N);
  vector<int> bloop, m1;
  REP(i, N) {
    if (P[i] == -1)
      m1.emplace_back(i);
    else if (uf.issame(i, P[i]))
      bloop.emplace_back(i);
    else
      uf.merge(i, P[i]);
  }

  mint ans = mint(N - 1).pow(m1.size()) * bloop.size();
  vector<vector<mint>> dp(m1.size() + 1, vector<mint>(m1.size() + 1));
  dp[0][0] = 1;
  REP(i, m1.size()) {
    REP(j, m1.size()) {
      if (dp[i][j] == 0)
        continue;
      dp[i + 1][j] += dp[i][j];
      dp[i + 1][j + 1] += dp[i][j] * uf.size(m1[i]);
    }
    ans += mint(N - 1).pow(m1.size() - 1) * (uf.size(m1[i]) - 1);
  }

  FOR(i, 2, m1.size() + 1)
  ans += dp[m1.size()][i] * comb.fact(i - 1) * mint(N - 1).pow(m1.size() - i);

  ans = mint(N - 1).pow(m1.size()) * N - ans;
  cout << ans << endl;

  return 0;
}


Error: -6
double free or corruption (out)


Fixed submission:

#include <bits/stdc++.h>
using namespace std;
#define FOR(i, a, b) for (int i = (a); i < (b); ++i)
#define REP(i, n) FOR(i, 0, n)
#define ALL(v) begin(v), end(v)
#define fi first
#define se second
template <typename A, typename B> inline bool chmax(A &a, B b) {
  if (a < b) {
    a = b;
    return 1;
  }
  return 0;
}
template <typename A, typename B> inline bool chmin(A &a, B b) {
  if (a > b) {
    a = b;
    return 1;
  }
  return 0;
}
using ll = long long;
using pii = pair<int, int>;
constexpr ll INF = 1ll << 30;
constexpr ll longINF = 1ll << 60;
constexpr ll MOD = 1000000007;
constexpr bool debug = 0;
//---------------------------------//

struct UnionFind {
public:
  using size_type = std::size_t;

  UnionFind(size_type n) : n(n), size_(n, 1) {
    par.resize(n);
    std::iota(par.begin(), par.end(), 0);
  }

  size_type size(size_type x) { return size_[find(x)]; }

  size_type find(size_type x) {
    assert(x < n);
    while (par[x] != x) {
      par[x] = par[par[x]];
      x = par[x];
    }
    return x;
  }

  void merge(size_type x, size_type y) {
    x = find(x);
    y = find(y);
    if (x == y)
      return;
    if (size(x) > size(y))
      std::swap(x, y);
    par[x] = y;
    size_[y] += size_[x];
  }

  bool issame(size_type x, size_type y) { return find(x) == find(y); }

private:
  size_type n;
  std::vector<size_type> size_, par;
};

template <int M> struct ModInt {
public:
  using value_type = long long;

  ModInt(value_type val = 0) : val(val < 0 ? (M - (-val % M)) % M : val % M) {}

  explicit operator bool() const noexcept { return val; }
  bool operator==(const ModInt &rhs) const noexcept { return val == rhs.val; }
  bool operator!=(const ModInt &rhs) const noexcept { return !(*this == rhs); }
  ModInt operator+() const noexcept { return ModInt(*this); }
  ModInt operator-() const noexcept { return ModInt(0) -= *this; }
  ModInt operator+(const ModInt &rhs) const noexcept {
    return ModInt(*this) += rhs;
  }
  ModInt operator-(const ModInt &rhs) const noexcept {
    return ModInt(*this) -= rhs;
  }
  ModInt operator*(const ModInt &rhs) const noexcept {
    return ModInt(*this) *= rhs;
  }
  ModInt operator/(const ModInt &rhs) const noexcept {
    return ModInt(*this) /= rhs;
  }

  ModInt &operator+=(const ModInt &rhs) noexcept {
    val += rhs.val;
    if (val >= M)
      val -= M;
    return *this;
  }
  ModInt &operator-=(const ModInt &rhs) noexcept {
    if (val < rhs.val)
      val += M;
    val -= rhs.val;
    return *this;
  }
  ModInt &operator*=(const ModInt &rhs) noexcept {
    val = val * rhs.val % M;
    return *this;
  }
  ModInt &operator/=(const ModInt &rhs) noexcept {
    *this *= rhs.inverse();
    return *this;
  }

  ModInt pow(value_type n) const {
    ModInt res = 1, x = val;
    if (n < 0) {
      x = x.inverse();
      n = -n;
    }
    while (n) {
      if (n & 1)
        res *= x;
      x *= x;
      n >>= 1;
    }
    return res;
  }

  ModInt inverse() const {
    long long a = val, a1 = 1, a2 = 0, b = M, b1 = 0, b2 = 1;
    while (b > 0) {
      value_type q = a / b, r = a % b;
      value_type nb1 = a1 - q * b1, nb2 = a2 - q * b2;
      a = b;
      b = r;
      a1 = b1;
      b1 = nb1;
      a2 = b2;
      b2 = nb2;
    }
    assert(a == 1);
    return a1;
  }

  const value_type &get() const noexcept { return val; }
  static decltype(M) get_mod() noexcept { return M; }

  friend std::ostream &operator<<(std::ostream &os, const ModInt &rhs) {
    return os << rhs.val;
  }
  friend std::istream &operator>>(std::istream &is, ModInt &rhs) {
    value_type x;
    is >> x;
    rhs = ModInt(x);
    return is;
  }

private:
  value_type val;
};
using mint = ModInt<MOD>;

template <typename T> struct Combination {
public:
  using size_type = std::size_t;

  Combination(size_type sz = 1) : _fact(1, 1), _finv(1, 1), _inv(1, 1) {
    build(sz);
  }

  T fact(size_type k) {
    if (k >= T::get_mod())
      return 0;
    build(k);
    return _fact[k];
  }
  T finv(size_type k) {
    assert(k < T::get_mod());
    build(k);
    return _finv[k];
  }
  T inv(size_type k) {
    assert(k > 0 && k < T::get_mod());
    build(k);
    return _inv[k];
  }

  T operator()(int n, int r) { return c(n, r); }
  T c(int n, int r) {
    if (r < 0 || n < r)
      return 0;
    return fact(n) * finv(r) * finv(n - r);
  }

private:
  std::vector<T> _fact, _finv, _inv;
  static constexpr size_type MAX_LIMIT = 50000000;

  void build(size_type k) {
    if (_fact.size() > k)
      return;
    assert(k < MAX_LIMIT);
    size_type sz = std::min({MAX_LIMIT, static_cast<size_type>(T::get_mod()),
                             std::max(_fact.size() * 2, k + 1)});
    size_type presz = _fact.size();
    _fact.resize(sz);
    _finv.resize(sz);
    _inv.resize(sz);

    for (size_type i = presz; i < sz; ++i)
      _fact[i] = _fact[i - 1] * i;
    _finv[sz - 1] = T(_fact[sz - 1]).inverse();
    for (size_type i = sz - 1; i > presz; --i) {
      _finv[i - 1] = _finv[i] * i;
      _inv[i] = _fact[i - 1] * _finv[i];
    }
    _inv[presz] = _fact[presz - 1] * _finv[presz];
  }
};
using Comb = Combination<mint>;
Comb comb;

int main() {
  int N;
  cin >> N;
  vector<int> P(N), minus(N);
  REP(i, N) {
    scanf("%d", &P[i]);
    if (P[i] > 0)
      --P[i];
    minus[P[i]] = true;
  }

  UnionFind uf(N);
  vector<int> bloop, m1;
  REP(i, N) {
    if (P[i] == -1)
      m1.emplace_back(i);
    else if (uf.issame(i, P[i]))
      bloop.emplace_back(i);
    else
      uf.merge(i, P[i]);
  }

  mint ans = mint(N - 1).pow(m1.size()) * bloop.size();
  vector<vector<mint>> dp(m1.size() + 1, vector<mint>(m1.size() + 1));
  dp[0][0] = 1;
  REP(i, m1.size()) {
    REP(j, m1.size()) {
      if (dp[i][j] == 0)
        continue;
      dp[i + 1][j] += dp[i][j];
      dp[i + 1][j + 1] += dp[i][j] * uf.size(m1[i]);
    }
    ans += mint(N - 1).pow(m1.size() - 1) * (uf.size(m1[i]) - 1);
  }

  FOR(i, 2, m1.size() + 1)
  ans += dp[m1.size()][i] * comb.fact(i - 1) * mint(N - 1).pow(m1.size() - i);

  ans = mint(N - 1).pow(m1.size()) * N - ans;
  cout << ans << endl;

  return 0;
}