1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73
| #include <bits/stdc++.h> #include <tr2/dynamic_bitset> using namespace std; using tr2::dynamic_bitset;
static void dfs_siz(size_t u, size_t fa, const vector<vector<size_t>> &tree, vector<size_t> &siz) { siz[u] = 1; for (size_t v : tree[u]) if (v != fa) dfs_siz(v, u, tree, siz), siz[u] += siz[v]; }
static void dfs_weight(size_t u, size_t fa, const vector<vector<size_t>> &tree, vector<size_t> &siz, vector<size_t> &weight) { siz[u] = 1; weight[u] = 0; for (size_t v : tree[u]) if (v != fa) dfs_weight(v, u, tree, siz, weight), siz[u] += siz[v], weight[u] = max(weight[u], siz[v]); weight[u] = max(weight[u], tree.size() - siz[u]); }
int main() { cin.tie(nullptr)->sync_with_stdio(false); size_t n; cin >> n; vector<vector<size_t>> tree(n); for (size_t i = 1; i < n; ++i) { size_t f; cin >> f; tree[i].emplace_back(f - 1); tree[f - 1].emplace_back(i); }
size_t root = [&]() -> size_t { vector<size_t> siz(n), weight(n); dfs_weight(0, 0, tree, siz, weight); size_t cur = 0; for (size_t i = 0; i < n; ++i) if (weight[i] < weight[cur]) cur = i; return cur; }();
vector<size_t> siz(n); dfs_siz(root, root, tree, siz); uint64_t ret = 0; for (size_t i = 0; i < n; ++i) ret += siz[i];
vector<size_t> son_siz(n); for (size_t son : tree[root]) ++son_siz[siz[son]];
for (size_t i = 1; i < n; ++i) while (son_siz[i] > 2) son_siz[i] -= 2, ++son_siz[i << 1];
size_t half_n = (n - 1) >> 1; dynamic_bitset<> F(half_n + 1); F.set(0); for (size_t w = 1; w < n; ++w) while (son_siz[w]--) F |= F << w; ret += [&]() -> uint64_t { for (size_t i = half_n; ~i; --i) if (F[i]) return i * (n - 1 - i); return 0; }(); cout << ret << '\n'; return 0; }
|