#include <bits/stdc++.h>
using namespace std;
template <typename T>
inline int Chkmax(T &a, T b) {
  return a < b ? a = b, 1 : 0;
}
template <typename T>
inline int Chkmin(T &a, T b) {
  return a > b ? a = b, 1 : 0;
}
inline void proc_status() {
  ifstream t("/proc/self/status");
  cerr << string(istreambuf_iterator<char>(t), istreambuf_iterator<char>())
       << endl;
}
template <typename T>
T read() {
  T sum = 0, fl = 1;
  char ch = getchar();
  for (; !isdigit(ch); ch = getchar())
    if (ch == '-') fl = -1;
  for (; isdigit(ch); ch = getchar()) sum = (sum << 3) + (sum << 1) + ch - '0';
  return sum * fl;
}
const int Maxn = 5e5 + 100;
int N, fa[Maxn], root, dep[Maxn], dfn[Maxn], dfs_clock, size[Maxn], son[Maxn],
    top[Maxn];
int e, Begin[Maxn], To[Maxn << 1], Next[Maxn << 1];
inline void add_edge(int first, int second) {
  To[++e] = second;
  Next[e] = Begin[first];
  Begin[first] = e;
}
vector<int> vec[Maxn];
int Maxdep;
inline void dfs(int first) {
  dep[first] = dep[fa[first]] + 1, size[first] = 1;
  Chkmax(Maxdep, dep[first]);
  vec[dep[first]].push_back(first);
  for (int i = Begin[first]; i; i = Next[i]) {
    int second = To[i];
    dfs(second);
    size[first] += size[second];
    if (size[second] > size[son[first]]) son[first] = second;
  }
}
inline void dfs(int first, int now) {
  dfn[first] = ++dfs_clock, top[first] = now;
  if (son[first]) dfs(son[first], now);
  for (int i = Begin[first]; i; i = Next[i]) {
    int second = To[i];
    if (second == fa[first] || second == son[first]) continue;
    dfs(second, second);
  }
}
long long Ans[Maxn];
namespace SEG {
struct tree {
  long long sum, tag;
} Tree[Maxn << 2];
inline void push_up(int root) {
  Tree[root].sum = Tree[(root << 1)].sum + Tree[(root << 1 | 1)].sum;
}
inline void push_down(int root, int l, int r, int mid) {
  if (!Tree[root].tag) return;
  Tree[(root << 1)].tag += Tree[root].tag,
      Tree[(root << 1 | 1)].tag += Tree[root].tag;
  Tree[(root << 1)].sum += Tree[root].tag * (mid - l + 1),
      Tree[(root << 1 | 1)].sum += Tree[root].tag * (r - mid);
  Tree[root].tag = 0;
}
inline void update(int root, int l, int r, int first, int second, int z) {
  if (first <= l && r <= second) {
    Tree[root].sum += 1ll * (r - l + 1) * z;
    Tree[root].tag += z;
    return;
  }
  int mid = l + r >> 1;
  push_down(root, l, r, mid);
  if (first <= mid) update((root << 1), l, mid, first, second, z);
  if (second > mid) update((root << 1 | 1), mid + 1, r, first, second, z);
  push_up(root);
}
inline long long query(int root, int l, int r, int first, int second) {
  if (first <= l && r <= second) return Tree[root].sum;
  int mid = l + r >> 1;
  long long ans = 0;
  push_down(root, l, r, mid);
  if (first <= mid) ans += query((root << 1), l, mid, first, second);
  if (second > mid) ans += query((root << 1 | 1), mid + 1, r, first, second);
  return ans;
}
}  // namespace SEG
inline void Update(int first) {
  while (first) {
    SEG ::update(1, 1, N, dfn[top[first]], dfn[first], 1);
    first = fa[top[first]];
  }
}
inline long long Query(int first) {
  long long ans = 0;
  while (first) {
    ans += SEG ::query(1, 1, N, dfn[top[first]], dfn[first]);
    first = fa[top[first]];
  }
  return ans;
}
inline void Solve() {
  dfs(root);
  dfs(root, root);
  for (int i = 1; i <= Maxdep; ++i) {
    for (int j = 0; j < vec[i].size(); ++j) Update(vec[i][j]);
    for (int j = 0; j < vec[i].size(); ++j) Ans[vec[i][j]] = Query(vec[i][j]);
  }
  for (int i = 1; i <= N; ++i) printf("%lld ", Ans[i] - dep[i]);
}
inline void Input() {
  N = read<int>();
  for (int i = 1; i <= N; ++i)
    fa[i] = read<int>(), add_edge(fa[i], i), (!fa[i]) ? (root = i) : 0;
}
int main() {
  Input();
  Solve();
  return 0;
}
