Problem p02666 (C++) — buggy submission, verdict: Time Limit Exceeded

#include <bits/stdc++.h>
using namespace std;

// template {{{
#define pb push_back
#define eb emplace_back
#define mp make_pair
#define mt make_tuple
#define lb lower_bound
#define ub upper_bound
#define f first
#define s second
#define resz resize

#define sz(x) int((x).size())
#define all(x) (x).begin(), (x).end()

#define FOR(i, a, b) for (int i = (a); i < (b); i++)
#define F0R(i, a) for (int i = 0; i < (a); i++)
#define FORd(i, a, b) for (int i = (b)-1; i >= (a); i--)
#define F0Rd(i, a) for (int i = (a)-1; i >= 0; i--)
#define trav(a, x) for (auto &a : x)

#define sort_by(x, y)                                                          \\
  sort(all(x), [&](const auto &a, const auto &b) { return y; })

using ll = long long;
using ld = long double;
using vi = vector<int>;
using vvi = vector<vi>;
using vll = vector<ll>;
using vvll = vector<vll>;
using vb = vector<bool>;
using vd = vector<double>;
using vs = vector<string>;

using pii = pair<int, int>;
using pll = pair<ll, ll>;
using pdd = pair<double, double>;

using vpii = vector<pii>;
using vvpii = vector<vpii>;
using vpll = vector<pll>;
using vvpll = vector<vpll>;
using vpdd = vector<pdd>;
using vvpdd = vector<vpdd>;

template <typename T> void ckmin(T &a, const T &b) { a = min(a, b); }
template <typename T> void ckmax(T &a, const T &b) { a = max(a, b); }

template <typename T> using max_heap = priority_queue<T>;
template <typename T> using min_heap = priority_queue<T, vector<T>, greater<T>>;

mt19937_64 rng(chrono::steady_clock::now().time_since_epoch().count());

namespace __input {
template <class T1, class T2> void re(pair<T1, T2> &p);
template <class T> void re(vector<T> &a);
template <class T, size_t SZ> void re(array<T, SZ> &a);

template <class T> void re(T &x) { cin >> x; }
void re(double &x) {
  string t;
  re(t);
  x = stod(t);
}
template <class Arg, class... Args> void re(Arg &first, Args &...rest) {
  re(first);
  re(rest...);
}

template <class T1, class T2> void re(pair<T1, T2> &p) { re(p.f, p.s); }
template <class T> void re(vector<T> &a) { F0R(i, sz(a)) re(a[i]); }
template <class T, size_t SZ> void re(array<T, SZ> &a) { F0R(i, SZ) re(a[i]); }
} // namespace __input
using namespace __input;

namespace __output {
template <class T1, class T2> void pr(const pair<T1, T2> &x);
template <class T, size_t SZ> void pr(const array<T, SZ> &x);
template <class T> void pr(const vector<T> &x);
template <class T> void pr(const deque<T> &x);
template <class T> void pr(const set<T> &x);
template <class T1, class T2> void pr(const map<T1, T2> &x);

template <class T> void pr(const T &x) { cout << x; }
template <class Arg, class... Args>
void pr(const Arg &first, const Args &...rest) {
  pr(first);
  pr(rest...);
}

template <class T1, class T2> void pr(const pair<T1, T2> &x) {
  pr("{", x.f, ", ", x.s, "}");
}
template <class T, bool pretty = true> void prContain(const T &x) {
  if (pretty)
    pr("{");
  bool fst = 1;
  for (const auto &a : x)
    pr(!fst ? pretty ? ", " : " " : "", a), fst = 0;
  if (pretty)
    pr("}");
}
template <class T> void pc(const T &x) {
  prContain<T, false>(x);
  pr("\\n");
}
template <class T, size_t SZ> void pr(const array<T, SZ> &x) { prContain(x); }
template <class T> void pr(const vector<T> &x) { prContain(x); }
template <class T> void pr(const deque<T> &x) { prContain(x); }
template <class T> void pr(const set<T> &x) { prContain(x); }
template <class T1, class T2> void pr(const map<T1, T2> &x) { prContain(x); }

void ps() { pr("\\n"); }
template <class Arg> void ps(const Arg &first) {
  pr(first);
  ps();
}
template <class Arg, class... Args>
void ps(const Arg &first, const Args &...rest) {
  pr(first, " ");
  ps(rest...);
}
} // namespace __output
using namespace __output;

#define TRACE(x) x
#define __pn(x) pr(#x, " = ")
#define pd(...) __pn((__VA_ARGS__)), ps(__VA_ARGS__), cout << flush

namespace __numeric {
template <typename T>
typename enable_if<is_integral<T>::value, T>::type floor(T n, T d) {
  assert(d != 0);
  if (d < 0)
    tie(n, d) = mp(-n, -d);
  return n / d - ((n < 0) && (n % d));
}
template <typename T>
typename enable_if<is_integral<T>::value, T>::type ceil(T n, T d) {
  assert(d != 0);
  if (d < 0)
    tie(n, d) = mp(-n, -d);
  return n / d + ((n > 0) && (n % d));
}
}; // namespace __numeric
using namespace __numeric;

namespace __algorithm {
template <typename T> void dedup(vector<T> &v) {
  sort(all(v));
  v.erase(unique(all(v)), v.end());
}
template <typename T>
typename vector<T>::iterator find(vector<T> &v, const T &x) {
  auto it = lower_bound(all(v), x);
  return it != v.end() && *it == x ? it : v.end();
}
template <typename T> size_t index(vector<T> &v, const T &x) {
  auto it = find(v, x);
  assert(it != v.end() && *it == x);
  return it - v.begin();
}
template <typename C, typename T, typename OP>
vector<T> prefixes(const C &v, T id, OP op) {
  vector<T> r(sz(v) + 1, id);
  F0R(i, sz(v)) r[i + 1] = op(r[i], v[i]);
  return r;
}
template <typename C, typename T, typename OP>
vector<T> suffixes(const C &v, T id, OP op) {
  vector<T> r(sz(v) + 1, id);
  F0Rd(i, sz(v)) r[i] = op(v[i], r[i + 1]);
  return r;
}
} // namespace __algorithm
using namespace __algorithm;

#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-parameter"
struct monostate {
  friend istream &operator>>(istream &is, const monostate &ms) { return is; }
  friend ostream &operator<<(ostream &os, const monostate &ms) { return os; }
  friend monostate operator+(const monostate &a, const monostate &b) {
    return a;
  }
} ms;
#pragma GCC diagnostic pop

namespace __io {
void setIn(string s) { freopen(s.c_str(), "r", stdin); }
void setOut(string s) { freopen(s.c_str(), "w", stdout); }
void setIO(string s = "") {
  ios_base::sync_with_stdio(0);
  cin.tie(0);
  cout << fixed << setprecision(15);
  if (sz(s)) {
    setIn(s + ".in"), setOut(s + ".out");
  }
}
} // namespace __io
using namespace __io;
// }}}

// union_find {{{
struct union_find {
  struct node {
    int par, rnk, size;
    node(int id = 0) : par(id), rnk(0), size(1) {}
  };

  vector<node> uf;
  union_find(int N = 0) : uf(N) {
    for (int i = 0; i < N; i++)
      uf[i] = node(i);
  }

  int rep(int i) {
    if (i != uf[i].par)
      uf[i].par = rep(uf[i].par);
    return uf[i].par;
  }

  bool unio(int a, int b) {
    a = rep(a), b = rep(b);
    if (a == b)
      return false;
    if (uf[a].rnk < uf[b].rnk)
      swap(a, b);
    uf[b].par = a;
    uf[a].size += uf[b].size;
    if (uf[a].rnk == uf[b].rnk)
      uf[a].rnk++;
    return true;
  }

  node &operator[](int i) { return uf[rep(i)]; }

  friend void pr(const union_find &u) {
    pr("{");
    bool f = 1;
    for (int i = 0; i < sz(u.uf); i++)
      if (u.uf[i].par == i) {
        if (!f)
          pr(", ");
        else
          f = 0;
        pr("[ ", i, " | rank=", u.uf[i].rnk, " size=", u.uf[i].size, " ]");
      }
    pr("}");
  }
};
// }}}

// modnum {{{
using v_t = int;
using vv_t = ll;
template <v_t MOD> struct modnum {
  v_t v;
  modnum() : v(0) {}
  modnum(vv_t _v) : v(_v % MOD) {
    if (v < 0)
      v += MOD;
  }
  explicit operator v_t() const { return v; }
  friend istream &operator>>(istream &i, modnum &n) {
    vv_t w;
    i >> w;
    n = modnum(w);
    return i;
  }
  friend ostream &operator<<(ostream &o, const modnum &n) { return o << n.v; }

  friend bool operator==(const modnum &a, const modnum &b) {
    return a.v == b.v;
  }
  friend bool operator!=(const modnum &a, const modnum &b) {
    return a.v != b.v;
  }

  static unsigned fast_mod(uint64_t x, unsigned m = MOD) {
#if !defined(_WIN32) || defined(_WIN64)
    return x % m;
#endif
    // x must be less than 2^32 * m so that x / m fits in a 32-bit integer.
    unsigned x_high = x >> 32, x_low = (unsigned)x, quot, rem;
    asm("divl %4\\n" : "=a"(quot), "=d"(rem) : "d"(x_high), "a"(x_low), "r"(m));
    return rem;
  }

  modnum &operator+=(const modnum &o) {
    v += o.v;
    if (v >= MOD)
      v -= MOD;
    return *this;
  }
  modnum &operator-=(const modnum &o) {
    v -= o.v;
    if (v < 0)
      v += MOD;
    return *this;
  }
  modnum &operator*=(const modnum &o) {
    v = fast_mod(vv_t(v) * o.v);
    return *this;
  }
  modnum operator-() {
    modnum res;
    if (v)
      res.v = MOD - v;
    return res;
  }
  friend modnum operator+(const modnum &a, const modnum &b) {
    return modnum(a) += b;
  }
  friend modnum operator-(const modnum &a, const modnum &b) {
    return modnum(a) -= b;
  }
  friend modnum operator*(const modnum &a, const modnum &b) {
    return modnum(a) *= b;
  }

  modnum pow(vv_t e) const {
    if (e < 0)
      return 1 / this->pow(-e);
    if (e == 0)
      return 1;
    if (e & 1)
      return *this * this->pow(e - 1);
    return (*this * *this).pow(e / 2);
  }

  modnum inv() const {
    v_t g = MOD, x = 0, y = 1;
    for (v_t r = v; r != 0;) {
      v_t q = g / r;
      g %= r;
      swap(g, r);
      x -= q * y;
      swap(x, y);
    }

    assert(g == 1);
    assert(y == MOD || y == -MOD);
    return x < 0 ? x + MOD : x;
  }
  modnum &operator/=(const modnum &o) { return (*this) *= o.inv(); }
  friend modnum operator/(const modnum &a, const modnum &b) {
    return modnum(a) /= modnum(b);
  }

  static constexpr v_t totient() {
    v_t tot = MOD, tmp = MOD;
    for (v_t p = 2; p * p <= tmp; p++)
      if (tmp % p == 0) {
        tot = tot / p * (p - 1);
        while (tmp % p == 0)
          tmp /= p;
      }
    if (tmp > 1)
      tot = tot / tmp * (tmp - 1);
    return tot;
  }

  static v_t primitive_root() {
    if (MOD == 1)
      return 0;
    if (MOD == 2)
      return 1;

    v_t tot = totient(), tmp = tot;
    vi tot_pr;
    for (v_t p = 2; p * p <= tmp; p++)
      if (tot % p == 0) {
        tot_pr.push_back(p);
        while (tmp % p == 0)
          tmp /= p;
      }
    if (tmp > 1)
      tot_pr.push_back(tmp);

    for (v_t r = 2; r < MOD; r++)
      if (__gcd(r, MOD) == 1) {
        bool root = true;
        for (v_t p : tot_pr)
          root &= modnum(r).pow(tot / p) != 1;
        if (root)
          return r;
      }
    assert(false);
  }

  static modnum generator() {
    static modnum g = primitive_root();
    return g;
  }
  static v_t discrete_log(modnum v) {
    static const v_t M = ceil(sqrt(MOD));
    static unordered_map<v_t, v_t> table;
    if (table.empty()) {
      modnum e = 1;
      for (v_t i = 0; i < M; i++) {
        table[e.v] = i;
        e *= generator();
      }
    }
    static modnum f = generator().pow(totient() - M);

    for (v_t i = 0; i < M; i++) {
      if (table.count(v.v))
        return table[v.v] + i * M;
      v *= f;
    }
    assert(false);
  }

  static modnum unity_root(int deg) {
    assert(totient() % deg == 0);
    return generator().pow(totient() / deg);
  }

  static modnum unity_root(int deg, int pow) {
    static vector<modnum> table{0, 1};
    while (sz(table) <= deg) {
      modnum w = unity_root(sz(table));
      for (int i = sz(table) / 2, s = sz(table); i < s; i++) {
        table.push_back(table[i]);
        table.push_back(table[i] * w);
      }
    }
    return table[deg + (pow < 0 ? deg + pow : pow)];
  }

  static modnum factorial(int n) {
    static vector<modnum> fact = {1};
    assert(n >= 0);
    if (sz(fact) <= n) {
      int had = sz(fact);
      fact.resize(n + 1);
      for (int i = had; i <= n; i++)
        fact[i] = fact[i - 1] * i;
    }
    return fact[n];
  }
  static modnum inverse_factorial(int n) {
    static vector<modnum> finv = {1};
    assert(n >= 0);
    if (sz(finv) <= n) {
      int had = sz(finv);
      finv.resz(n + 1), finv[n] = factorial(n).inv();
      for (int i = n - 1; i >= had; i--)
        finv[i] = finv[i + 1] * (i + 1);
    }
    return finv[n];
  }

  static modnum small_inv(int n) {
    assert(n > 0);
    return factorial(n - 1) * inverse_factorial(n);
  }

  static modnum ncr(int n, int r) {
    if (r < 0 || n < r)
      return 0;
    return factorial(n) * inverse_factorial(r) * inverse_factorial(n - r);
  }
};
// }}}
using mn = modnum<int(1e9 + 7)>;
using vmn = vector<mn>;
using vvmn = vector<vmn>;

int main() {
  setIO();

  int N;
  re(N);
  vi p(N);
  re(p);

  union_find uf(N);

  int K = 0;
  int C = N;

  F0R(i, N) {
    if (~p[i]) {
      C -= uf.unio(i, --p[i]);
    } else {
      C--;
      K++;
    }
  }

  vi with_root(N);
  F0R(i, N) {
    vb seen(N);
    int j = i, pj;
    for (; j != -1 && !seen[j]; pj = j, j = p[j])
      seen[j] = 1;
    if (j == -1)
      with_root[pj]++;
  }

  vmn pow(N + 1);
  pow[0] = 1;
  F0R(i, N) pow[i + 1] = pow[i] * (N - 1);

  mn ans = 0;

  vmn dp = {1};
  F0R(i, N) {
    if (with_root[i]) {
      ans += (with_root[i] - 1) * pow[K - 1];

      vmn DP(sz(dp) + 1);
      F0R(elts, sz(dp)) {
        DP[elts] += dp[elts];
        DP[elts + 1] += dp[elts] * with_root[i];
      }
      dp = DP;
    }
  }

  FOR(elts, 2, sz(dp)) {
    ans += mn::factorial(elts - 1) * dp[elts] * pow[K - elts];
  }

  ps((N - C) * pow[K] - ans);

  // did you check N=1? did you mix up N,M?
  // check your "infinity" and "null" values against the bounds
  return 0;
}


Error: TLE

Fixed submission:

#include <bits/stdc++.h>
using namespace std;

// template {{{
#define pb push_back
#define eb emplace_back
#define mp make_pair
#define mt make_tuple
#define lb lower_bound
#define ub upper_bound
#define f first
#define s second
#define resz resize

#define sz(x) int((x).size())
#define all(x) (x).begin(), (x).end()

#define FOR(i, a, b) for (int i = (a); i < (b); i++)
#define F0R(i, a) for (int i = 0; i < (a); i++)
#define FORd(i, a, b) for (int i = (b)-1; i >= (a); i--)
#define F0Rd(i, a) for (int i = (a)-1; i >= 0; i--)
#define trav(a, x) for (auto &a : x)

#define sort_by(x, y)                                                          \\
  sort(all(x), [&](const auto &a, const auto &b) { return y; })

using ll = long long;
using vi = vector<int>;
using vvi = vector<vi>;
using vll = vector<ll>;
using vvll = vector<vll>;
using vb = vector<bool>;
using vd = vector<double>;
using vs = vector<string>;

using pii = pair<int, int>;
using pll = pair<ll, ll>;
using pdd = pair<double, double>;

using vpii = vector<pii>;
using vpll = vector<pll>;
using vpdd = vector<pdd>;

template <typename T> void ckmin(T &a, const T &b) { a = min(a, b); }
template <typename T> void ckmax(T &a, const T &b) { a = max(a, b); }

mt19937_64 rng(chrono::steady_clock::now().time_since_epoch().count());

namespace __input {
template <class T1, class T2> void re(pair<T1, T2> &p);
template <class T> void re(vector<T> &a);
template <class T, size_t SZ> void re(array<T, SZ> &a);

template <class T> void re(T &x) { cin >> x; }
void re(double &x) {
  string t;
  re(t);
  x = stod(t);
}
template <class Arg, class... Args> void re(Arg &first, Args &...rest) {
  re(first);
  re(rest...);
}

template <class T1, class T2> void re(pair<T1, T2> &p) { re(p.f, p.s); }
template <class T> void re(vector<T> &a) { F0R(i, sz(a)) re(a[i]); }
template <class T, size_t SZ> void re(array<T, SZ> &a) { F0R(i, SZ) re(a[i]); }
} // namespace __input
using namespace __input;

namespace __output {
template <class T1, class T2> void pr(const pair<T1, T2> &x);
template <class T, size_t SZ> void pr(const array<T, SZ> &x);
template <class T> void pr(const vector<T> &x);
template <class T> void pr(const set<T> &x);
template <class T1, class T2> void pr(const map<T1, T2> &x);

template <class T> void pr(const T &x) { cout << x; }
template <class Arg, class... Args>
void pr(const Arg &first, const Args &...rest) {
  pr(first);
  pr(rest...);
}

template <class T1, class T2> void pr(const pair<T1, T2> &x) {
  pr("{", x.f, ", ", x.s, "}");
}
template <class T, bool pretty = true> void prContain(const T &x) {
  if (pretty)
    pr("{");
  bool fst = 1;
  for (const auto &a : x)
    pr(!fst ? pretty ? ", " : " " : "", a), fst = 0;
  if (pretty)
    pr("}");
}
template <class T> void pc(const T &x) {
  prContain<T, false>(x);
  pr("\\n");
}
template <class T, size_t SZ> void pr(const array<T, SZ> &x) { prContain(x); }
template <class T> void pr(const vector<T> &x) { prContain(x); }
template <class T> void pr(const set<T> &x) { prContain(x); }
template <class T1, class T2> void pr(const map<T1, T2> &x) { prContain(x); }

void ps() { pr("\\n"); }
template <class Arg> void ps(const Arg &first) {
  pr(first);
  ps();
}
template <class Arg, class... Args>
void ps(const Arg &first, const Args &...rest) {
  pr(first, " ");
  ps(rest...);
}
} // namespace __output
using namespace __output;

#define TRACE(x) x
#define __pn(x) pr(#x, " = ")
#define pd(...) __pn((__VA_ARGS__)), ps(__VA_ARGS__), cout << flush

namespace __algorithm {
template <typename T> void dedup(vector<T> &v) {
  sort(all(v));
  v.erase(unique(all(v)), v.end());
}
template <typename T>
typename vector<T>::const_iterator find(const vector<T> &v, const T &x) {
  auto it = lower_bound(all(v), x);
  return it != v.end() && *it == x ? it : v.end();
}
template <typename T> size_t index(const vector<T> &v, const T &x) {
  auto it = find(v, x);
  assert(it != v.end() && *it == x);
  return it - v.begin();
}

template <typename T1, typename T2>
typename vector<pair<T1, T2>>::iterator
lower_bound(const vector<pair<T1, T2>> &v, const T1 &x) {
  return lower_bound(all(v), x,
                     [](pair<T1, T2> a, pair<T1, T2> b) { return a.f < b.f; });
}
template <typename T1, typename T2>
typename vector<pair<T1, T2>>::iterator
upper_bound(const vector<pair<T1, T2>> &v, const T1 &x) {
  return upper_bound(all(v), x,
                     [](pair<T1, T2> a, pair<T1, T2> b) { return a.f < b.f; });
}
} // namespace __algorithm
using namespace __algorithm;

struct __monostate {
  friend istream &operator>>(istream &is,
                             const __attribute__((unused)) __monostate &ms) {
    return is;
  }
  friend ostream &operator<<(ostream &os,
                             const __attribute__((unused)) __monostate &ms) {
    return os;
  }
} ms;

namespace __io {
void setIn(string s) { freopen(s.c_str(), "r", stdin); }
void setOut(string s) { freopen(s.c_str(), "w", stdout); }
void setIO(string s = "") {
  ios_base::sync_with_stdio(0);
  cin.tie(0);
  cout << setprecision(15);
  if (sz(s)) {
    setIn(s + ".in"), setOut(s + ".out");
  }
}
} // namespace __io
using namespace __io;
// }}}

// modnum {{{
using v_t = int;
using vv_t = ll;
template <v_t MOD> struct modnum {
  v_t v;
  modnum() : v(0) {}
  modnum(vv_t _v) : v(_v % MOD) {
    if (v < 0)
      v += MOD;
  }
  explicit operator v_t() const { return v; }
  friend istream &operator>>(istream &i, modnum &n) {
    vv_t w;
    i >> w;
    n = modnum(w);
    return i;
  }
  friend ostream &operator<<(ostream &o, const modnum &n) { return o << n.v; }

  friend bool operator==(const modnum &a, const modnum &b) {
    return a.v == b.v;
  }
  friend bool operator!=(const modnum &a, const modnum &b) {
    return a.v != b.v;
  }

  static unsigned fast_mod(uint64_t x, unsigned m = MOD) {
#if !defined(_WIN32) || defined(_WIN64)
    return x % m;
#endif
    // x must be less than 2^32 * m so that x / m fits in a 32-bit integer.
    unsigned x_high = x >> 32, x_low = (unsigned)x, quot, rem;
    asm("divl %4\\n" : "=a"(quot), "=d"(rem) : "d"(x_high), "a"(x_low), "r"(m));
    return rem;
  }

  modnum &operator+=(const modnum &o) {
    v += o.v;
    if (v >= MOD)
      v -= MOD;
    return *this;
  }
  modnum &operator-=(const modnum &o) {
    v -= o.v;
    if (v < 0)
      v += MOD;
    return *this;
  }
  modnum &operator*=(const modnum &o) {
    v = fast_mod(vv_t(v) * o.v);
    return *this;
  }
  modnum operator-() {
    modnum res;
    if (v)
      res.v = MOD - v;
    return res;
  }
  friend modnum operator+(const modnum &a, const modnum &b) {
    return modnum(a) += b;
  }
  friend modnum operator-(const modnum &a, const modnum &b) {
    return modnum(a) -= b;
  }
  friend modnum operator*(const modnum &a, const modnum &b) {
    return modnum(a) *= b;
  }

  modnum pow(vv_t e) const {
    if (e < 0)
      return 1 / this->pow(-e);
    if (e == 0)
      return 1;
    if (e & 1)
      return *this * this->pow(e - 1);
    return (*this * *this).pow(e / 2);
  }

  modnum inv() const {
    v_t g = MOD, x = 0, y = 1;
    for (v_t r = v; r != 0;) {
      v_t q = g / r;
      g %= r;
      swap(g, r);
      x -= q * y;
      swap(x, y);
    }

    assert(g == 1);
    assert(y == MOD || y == -MOD);
    return x < 0 ? x + MOD : x;
  }
  modnum &operator/=(const modnum &o) { return (*this) *= o.inv(); }
  friend modnum operator/(const modnum &a, const modnum &b) {
    return modnum(a) /= modnum(b);
  }

  static constexpr v_t totient() {
    v_t tot = MOD, tmp = MOD;
    for (v_t p = 2; p * p <= tmp; p++)
      if (tmp % p == 0) {
        tot = tot / p * (p - 1);
        while (tmp % p == 0)
          tmp /= p;
      }
    if (tmp > 1)
      tot = tot / tmp * (tmp - 1);
    return tot;
  }

  static v_t primitive_root() {
    if (MOD == 1)
      return 0;
    if (MOD == 2)
      return 1;

    v_t tot = totient(), tmp = tot;
    vi tot_pr;
    for (v_t p = 2; p * p <= tmp; p++)
      if (tot % p == 0) {
        tot_pr.push_back(p);
        while (tmp % p == 0)
          tmp /= p;
      }
    if (tmp > 1)
      tot_pr.push_back(tmp);

    for (v_t r = 2; r < MOD; r++)
      if (__gcd(r, MOD) == 1) {
        bool root = true;
        for (v_t p : tot_pr)
          root &= modnum(r).pow(tot / p) != 1;
        if (root)
          return r;
      }
    assert(false);
  }

  static modnum generator() {
    static modnum g = primitive_root();
    return g;
  }
  static v_t discrete_log(modnum v) {
    static const v_t M = ceil(sqrt(MOD));
    static unordered_map<v_t, v_t> table;
    if (table.empty()) {
      modnum e = 1;
      for (v_t i = 0; i < M; i++) {
        table[e.v] = i;
        e *= generator();
      }
    }
    static modnum f = generator().pow(totient() - M);

    for (v_t i = 0; i < M; i++) {
      if (table.count(v.v))
        return table[v.v] + i * M;
      v *= f;
    }
    assert(false);
  }

  static modnum unity_root(int deg) {
    assert(totient() % deg == 0);
    return generator().pow(totient() / deg);
  }

  static modnum unity_root(int deg, int pow) {
    static vector<modnum> table{0, 1};
    while (sz(table) <= deg) {
      modnum w = unity_root(sz(table));
      for (int i = sz(table) / 2, s = sz(table); i < s; i++) {
        table.push_back(table[i]);
        table.push_back(table[i] * w);
      }
    }
    return table[deg + (pow < 0 ? deg + pow : pow)];
  }

  static modnum factorial(int n) {
    static vector<modnum> fact = {1};
    assert(n >= 0);
    if (sz(fact) <= n) {
      int had = sz(fact);
      fact.resize(n + 1);
      for (int i = had; i <= n; i++)
        fact[i] = fact[i - 1] * i;
    }
    return fact[n];
  }
  static modnum inverse_factorial(int n) {
    static vector<modnum> finv = {1};
    assert(n >= 0);
    if (sz(finv) <= n) {
      int had = sz(finv);
      finv.resz(n + 1), finv[n] = factorial(n).inv();
      for (int i = n - 1; i >= had; i--)
        finv[i] = finv[i + 1] * (i + 1);
    }
    return finv[n];
  }

  static modnum small_inv(int n) {
    assert(n > 0);
    return factorial(n - 1) * inverse_factorial(n);
  }

  static modnum ncr(int n, int r) {
    if (r < 0 || n < r)
      return 0;
    return factorial(n) * inverse_factorial(r) * inverse_factorial(n - r);
  }
};
// }}}
using mn = modnum<int(1e9 + 7)>;
using vmn = vector<mn>;
using vvmn = vector<vmn>;

// union_find {{{
struct union_find {
  struct node {
    int par, rnk, size;
    node(int id = 0) : par(id), rnk(0), size(1) {}
  };

  vector<node> uf;
  union_find(int N = 0) : uf(N) {
    for (int i = 0; i < N; i++)
      uf[i] = node(i);
  }

  int rep(int i) {
    if (i != uf[i].par)
      uf[i].par = rep(uf[i].par);
    return uf[i].par;
  }

  bool unio(int a, int b) {
    a = rep(a), b = rep(b);
    if (a == b)
      return false;
    if (uf[a].rnk < uf[b].rnk)
      swap(a, b);
    uf[b].par = a;
    uf[a].size += uf[b].size;
    if (uf[a].rnk == uf[b].rnk)
      uf[a].rnk++;
    return true;
  }

  node &operator[](int i) { return uf[rep(i)]; }

  friend void pr(const union_find &u) {
    pr("{");
    bool f = 1;
    for (int i = 0; i < sz(u.uf); i++)
      if (u.uf[i].par == i) {
        if (!f)
          pr(", ");
        else
          f = 0;
        pr("[ ", i, " | rank=", u.uf[i].rnk, " size=", u.uf[i].size, " ]");
      }
    pr("}");
  }
};
// }}}

int main() {
  setIO();

  const int MAXF = 5001;
  vvmn stir(MAXF, vmn(MAXF));

  stir[0][0] = 1;
  FOR(n, 2, MAXF) {
    FOR(k, 1, n / 2 + 1) {
      if (k == 1)
        stir[n][k] = mn::factorial(n - 1);
      else
        stir[n][k] = (n - 1) * (stir[n - 1][k] + stir[n - 2][k - 1]);
    }
  }

  int N;
  re(N);
  vi p(N);
  re(p);

  vmn pow(N + 1);
  pow[0] = 1;
  F0R(i, N) pow[i + 1] = pow[i] * (N - 1);

  union_find uf(N);

  int C = N;
  F0R(i, N) {
    if (p[i] != -1)
      C -= uf.unio(i, --p[i]);
  }

  vvmn f(N + 1, vmn(N + 1)), F = f;
  f[0][0] = 1;

  F0R(i, N) {
    if (p[i] == -1) {
      C--;

      int S = uf[i].size;

      trav(e, F) fill(all(e), 0);
      F0R(x, N + 1) {
        F0R(y, N + 1) {
          if (y + 1 <= N)
            F[x][y + 1] +=
                f[x][y] *
                (S - 1); // form cycle with just this unassigned element
          if (x + 1 <= N)
            F[x + 1][y] +=
                f[x][y] *
                S; // to be used in cycle with >= 2 unassigned elements
          F[x][y] += f[x][y] * (N - S); // assign freely outside of self
        }
      }
      swap(f, F);
    }
  }

  vvmn g(N + 1, vmn(N + 1, 0));

  F0R(y, N + 1) {
    F0R(x, N + 1) {
      F0R(k, N + 1) { g[y][k] += f[x][y] * stir[x][k]; }
    }
  }

  mn ans = 0;

  F0R(y, N + 1) {
    F0Rd(k, N + 1) {
      FOR(K, k + 1, N + 1)
      g[y][k] -= mn::ncr(K, k) * g[y][K];

      if (g[y][k].v) {
        ans += (N - C - y - k) * g[y][k];
      }
    }
  }

  ps(ans);

  return 0;
}