A Ancient Distance
阿新 • • 發佈:2020-08-17
#include<iostream> #include<cstring> #include<algorithm> #include<cmath> #include<cstdlib> #include<climits> #include<stack> #include<vector> #include<queue> #include<set> #include<bitset> #include<map> //#include<regex> #include<cstdio> #include <iomanip> #pragma GCC optimize(2) #define up(i,a,b) for(int i=a;i<b;i++) #define dw(i,a,b) for(int i=a;i>b;i--) #define upd(i,a,b) for(int i=a;i<=b;i++) #define dwd(i,a,b) for(int i=a;i>=b;i--) //#define local typedef long long ll; typedef unsigned long long ull; const double esp = 1e-6; const double pi = acos(-1.0); const int INF = 0x3f3f3f3f; const int inf = 1e9; using namespace std; ll read() { char ch = getchar(); ll x = 0, f = 1; while (ch<'0' || ch>'9') { if (ch == '-')f = -1; ch = getchar(); } while (ch >= '0' && ch <= '9') { x = x * 10 + ch - '0'; ch = getchar(); } return x * f; } typedef pair<int, int> pir; #define lson l,mid,root<<1 #define rson mid+1,r,root<<1|1 #define lrt root<<1 #define rrt root<<1|1 const int N = 2e5 + 10; vector<int>vec[N]; int n; int st = 0; int f[N], dfn[N], ed[N], par[N][25]; int rk[N]; struct seg { int mx[N << 2]; int mxx[N << 2]; void pushup(int root) { mx[root] = max(mx[root << 1], mx[root << 1 | 1]); } void build(int l, int r, int root) { if (l == r) { mx[root] = mxx[root] = f[rk[l]]; return; } int mid = (l + r) >> 1; build(lson); build(rson); pushup(root); mxx[root] = mx[root]; } void update(int l, int r, int root, int L, int R) { if (L <= l && r <= R) { mx[root] = -1; return; } int mid = (l + r) >> 1; if (L <= mid)update(lson, L, R); if (R > mid)update(rson, L, R); pushup(root); } void rebuild(int l, int r, int root, int L, int R) { mx[root] = mxx[root]; if (L <= l && r <= R) { return; } int mid = (l + r) >> 1; if (L <= mid)rebuild(lson, L, R); if (R > mid)rebuild(rson, L, R); pushup(root); } int query(int l, int r, int root) { if (l == r)return l; int mid = (l + r) >> 1; if (mx[root] == -1)return -1; if (mx[root << 1] < mx[root << 1 | 1])return query(rson); else return query(lson); } }T; void dfs(int u, int fa) { par[u][0] = fa; upd(i, 1, 22) { par[u][i] = par[par[u][i - 1]][i - 1]; } f[u] = f[fa] + 1; dfn[u] = ++st; rk[st] = u; for (auto k : vec[u]) { if (k == fa)continue; dfs(k, u); } ed[u] = st; } vector<pir>temp; vector<int>ans; int main() { while (~scanf("%d", &n)) { st = 0; upd(i, 1, n)vec[i].clear(); ans.clear(); int u; upd(i, 2, n) { u = read(); vec[i].push_back(u); vec[u].push_back(i); } int need = 0; dfs(1, 1); T.build(1, st, 1); ans.resize(n + 1, -1); ans[0] = n; for (int d = 1; d <= n-1; d++) { int cnt = 0; temp.clear(); while (1) { int last = T.query(1, st, 1); if (last == -1)break; last = rk[last]; cnt++; dwd(i, 22, 0) { if (d >> i & 1)last = par[last][i]; } temp.push_back({ dfn[last],ed[last] }); T.update(1, st, 1, dfn[last], ed[last]); } ans[d] = cnt; for (auto k : temp) { T.rebuild(1, st, 1, k.first, k.second); } if (cnt == 1)break; } ll sum = 0; upd(d, 1, n-1) { if (ans[d] == -1)break; sum += 1ll * (ans[d - 1] - ans[d])*d; //if (ans[d] == 1)break; } printf("%lld\n", sum); } return 0; }