#include <bits/stdc++.h>
using namespace std;
using ll = long long;
void dfs_sz(int x, vector<vector<int>> &sons, vector<int> &rk,
            vector<int> &subtree) {
  subtree[x] = 1;
  for (int &dest : sons[x]) {
    rk[dest] = rk[x] + 1;
    dfs_sz(dest, sons, rk, subtree);
    subtree[x] += subtree[dest];
    if (subtree[dest] > subtree[sons[x].front()]) swap(dest, sons[x].front());
  }
}
void dfs_hld(int x, const vector<vector<int>> &sons, vector<int> &in,
             vector<int> &out, int &tmr, vector<int> &last_heavy) {
  in[x] = tmr++;
  for (int dest : sons[x]) {
    last_heavy[dest] = (dest == sons[x].front() ? last_heavy[x] : dest);
    dfs_hld(dest, sons, in, out, tmr, last_heavy);
  }
  out[x] = tmr;
}
int up(int n) {
  int ans = 1;
  while (ans < n) ans *= 2;
  return ans;
}
struct segtree {
  vector<ll> sum, to_add;
  int tsz;
  segtree(int n) {
    tsz = up(n);
    sum = to_add = vector<ll>(2 * tsz);
  }
  void upd(int v) { sum[v] = sum[2 * v] + sum[2 * v + 1]; }
  void apply(int v, int len, ll what) {
    to_add[v] += what;
    sum[v] += what * len;
  }
  void push(int v, int len) {
    if (to_add[v] != 0) {
      for (int son = 2 * v; son <= 2 * v + 1; son++) {
        apply(son, len / 2, to_add[v]);
      }
      to_add[v] = 0;
    }
  }
  void go_add(int v, int L, int R, int l, int r, int x) {
    if (r <= L || R <= l) return;
    if (l <= L && R <= r) {
      apply(v, R - L, x);
      return;
    }
    push(v, R - L);
    const int M = (L + R) / 2;
    go_add(2 * v, L, M, l, r, x);
    go_add(2 * v + 1, M, R, l, r, x);
    upd(v);
  }
  void add_seg(int l, int r, int x) { go_add(1, 0, tsz, l, r, x); }
  ll go_sum(int v, int L, int R, int l, int r) {
    if (r <= L || R <= l) return 0;
    if (l <= L && R <= r) {
      return sum[v];
    }
    push(v, R - L);
    const int M = (L + R) / 2;
    return go_sum(2 * v, L, M, l, r) + go_sum(2 * v + 1, M, R, l, r);
  }
  ll sum_seg(int l, int r) { return go_sum(1, 0, tsz, l, r); }
};
class pushfreesegtree {
  vector<ll> pushed, unpushed;
  ll add(int l, int r, int cl, int cr, int v, const ll &x) {
    if (r <= cl || cr <= l) return 0;
    if (l <= cl && cr <= r) {
      unpushed[v] += x;
      return x * (cr - cl);
    }
    const int ct = (cl + cr) / 2;
    const auto tmp =
        add(l, r, cl, ct, 2 * v, x) + add(l, r, ct, cr, 2 * v + 1, x);
    pushed[v] += tmp;
    return tmp;
  }
  ll sum(int l, int r, int cl, int cr, int v) {
    if (r <= cl || cr <= l) return 0;
    if (l <= cl && cr <= r) return pushed[v] + unpushed[v] * (cr - cl);
    const int ct = (cl + cr) / 2;
    return sum(l, r, cl, ct, 2 * v) + unpushed[v] * (min(r, cr) - max(l, cl)) +
           sum(l, r, ct, cr, 2 * v + 1);
  }

 public:
  pushfreesegtree(int n) : pushed(2 * up(n)), unpushed(2 * up(n)) {}
  ll sum_seg(int l, int r) { return sum(l, r, 0, pushed.size() / 2, 1); }
  void add_seg(int l, int r, const ll &x) {
    add(l, r, 0, pushed.size() / 2, 1, x);
  }
};
void solve(istream &cin = std::cin, ostream &cout = std::cout) {
  int n;
  cin >> n;
  vector<vector<int>> sons(n);
  vector<int> par(n);
  for (int i = 0; i < n; i++) {
    cin >> par[i];
    --par[i];
    if (par[i] != -1) sons[par[i]].push_back(i);
  }
  const int root = find(par.begin(), par.end(), -1) - par.begin();
  vector<int> rk(n), subtree(n);
  dfs_sz(root, sons, rk, subtree);
  vector<int> in(n), out(n), last_heavy(n);
  int tmr = 0;
  last_heavy[root] = root;
  dfs_hld(root, sons, in, out, tmr, last_heavy);
  vector<vector<int>> by_rk(n);
  for (int i = 0; i < n; i++) by_rk[rk[i]].push_back(i);
  vector<ll> ans(n);
  pushfreesegtree data(n);
  for (int h = 0; h < n; h++) {
    auto &cur = by_rk[h];
    sort(cur.begin(), cur.end(), [&](int x, int y) { return in[x] < in[y]; });
    for (int iter = 0; iter < 2; iter++) {
      {
        for (int i = 0, j; i < int(cur.size()); i = j) {
          j = i;
          while (j < int(cur.size()) && par[cur[i]] == par[cur[j]]) j++;
          int v = par[cur[i]], cnt = j - i;
          ll what_added = 0;
          while (v != -1) {
            int left = in[last_heavy[v]];
            int right = in[v];
            if (iter == 0)
              data.add_seg(left, right + 1, +cnt);
            else
              what_added += data.sum_seg(left, right + 1);
            v = par[last_heavy[v]];
          }
          if (iter == 1) {
            for (int k = i; k < j; k++) ans[cur[k]] += what_added;
          }
        }
      }
    }
  }
  for (int i = 0; i < n; i++) cout << ans[i] << " \n"[i + 1 == n];
  cout.flush();
}
void gen(stringstream &cout) {
  const int n = int(5e5);
  vector<int> par(n);
  for (int i = 1; i < n; i++) par[i] = (i - 1) / 2;
  par[0] = -1;
  vector<int> order(n);
  iota(order.begin(), order.end(), 0);
  mt19937 rng;
  shuffle(order.begin(), order.end(), rng);
  vector<int> reorpar(n);
  for (int i = 0; i < n; i++) {
    reorpar[order[i]] = (par[i] == -1 ? -1 : order[par[i]]);
  }
  cout << n << endl;
  for (int i = 0; i < n; i++) {
    cout << reorpar[i] + 1 << ' ';
  }
  cout << endl;
}
int main() {
  ios_base::sync_with_stdio(false);
  cin.tie(nullptr);
  solve();
  return 0;
}
