int n; int p[kMaxN], sz[kMaxN], mx[kMaxN], suf[kMaxN], pos[kMaxN]; std::vector<int> G[kMaxN];
constexprintqpow(int bs, int64_t idx = kMod - 2){ int ret = 1; for (; idx; idx >>= 1, bs = (int64_t)bs * bs % kMod) if (idx & 1) ret = (int64_t)ret * bs % kMod; return ret; }
inlineintadd(int x, int y){ return (x + y >= kMod ? x + y - kMod : x + y); } inlineintsub(int x, int y){ return (x >= y ? x - y : x - y + kMod); } inlinevoidinc(int &x, int y){ (x += y) >= kMod ? x -= kMod : x; } inlinevoiddec(int &x, int y){ (x -= y) < 0 ? x += kMod : x; }
voiddfs(int u, int fa){ std::vector<int> vsz; sz[u] = 1, mx[u] = 0; for (auto v : G[u]) { if (v == fa) continue; dfs(v, u); sz[u] += sz[v], mx[u] = std::max(mx[u], sz[v]); vsz.emplace_back(sz[v]); } mx[u] = std::max(mx[u], n - sz[u]); vsz.emplace_back(n - sz[u]); std::sort(vsz.begin(), vsz.end(), std::greater<>()); if (vsz.size() >= 3) { suf[vsz[1]] = std::max(suf[vsz[1]], vsz[2]); } }
voiddickdreamer(){ std::cin >> n; for (int i = 1; i <= n; ++i) G[i].clear(); std::fill_n(suf, n + 2, 0); for (int i = 2; i <= n; ++i) { std::cin >> p[i]; G[p[i]].emplace_back(i), G[i].emplace_back(p[i]); } dfs(1, 0); std::vector<int> vec; for (int i = 1; i <= n; ++i) vec.emplace_back(i); std::sort(vec.begin(), vec.end(), [&] (int i, int j) { return mx[i] < mx[j]; }); for (int i = 0; i < n; ++i) pos[vec[i]] = i; dfs(vec[0], 0); int ans = 0; for (int i = n; i; --i) { suf[i] = std::max(suf[i], suf[i + 1]); if (i > mx[vec[0]]) continue; int val = std::min(suf[i], i); if (val < i) { inc(ans, 2ll * i % kMod * getsum(1, val) % kMod); inc(ans, 4ll * i % kMod * getsum(val + 1, i - 1) % kMod); inc(ans, 2ll * i % kMod * i % kMod); } else { inc(ans, 2ll * i * getsum(1, i - 1) % kMod); inc(ans, 1ll * i * i % kMod); } } int now = getsum(n); for (int i = mx[vec[0]] + 1, j = 0; i <= n; ++i) { for (; j < n && mx[vec[j]] < i; ++j) { dec(now, getsum(sz[vec[j]])); for (auto v : G[vec[j]]) if (pos[v] > j) inc(now, getsum(sz[v])); } inc(ans, 2ll * i * now % kMod); } std::cout << ans << '\n'; }