#include <bits/stdc++.h>
#pragma GCC optimize("O3")
#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx")
using namespace std;
template <int N>
struct LinkingCuttingTree {
  struct node {
    int val{0}, cnt{0}, add{0};
    long long sum{0};
    bool rev{false};
    node *l, *r, *p, *path;
  };
  typedef node *pnode;
  node tr[N + 1];
  const pnode pNull;
  pnode tmp[N + 1];
  LinkingCuttingTree() : pNull(tr + N) { tr[N].sum = 0; }
  inline void upd(pnode v) {
    if (v == pNull) return;
    v->cnt = v->l->cnt + v->r->cnt + 1;
    v->sum = v->l->sum + v->r->sum + v->val;
    if (v->l->add) {
      v->sum += (long long)v->l->add * v->l->cnt;
    }
    if (v->r->add) {
      v->sum += (long long)v->r->add * v->r->cnt;
    }
    v->l->p = v;
    v->r->p = v;
  }
  inline void push(pnode v) {
    if (v == pNull) return;
    if (v->rev) {
      v->l->rev ^= 1;
      v->r->rev ^= 1;
      v->rev = 0;
      swap(v->l, v->r);
    }
    if (v->add) {
      v->l->add += v->add;
      v->r->add += v->add;
      v->val += v->add;
      v->sum += (long long)v->add * v->cnt;
      v->add = 0;
    }
  }
  inline void rotate(pnode v) {
    if (v == pNull || v->p == pNull) return;
    pnode f = v->p;
    if (f->l == v) {
      pnode old = v->r;
      v->r = f;
      f->l = old;
      v->path = f->path;
      v->p = f->p;
      if (f->p->l == f)
        f->p->l = v;
      else
        f->p->r = v;
      upd(f);
      upd(v);
    } else {
      pnode old = v->l;
      v->l = f;
      f->r = old;
      v->p = f->p;
      v->path = f->path;
      if (f->p->l == f)
        f->p->l = v;
      else
        f->p->r = v;
      upd(f);
      upd(v);
    }
  }
  inline void splay(pnode v) {
    if (v == pNull) return;
    int k = 0;
    pnode q = v;
    while (q != pNull) {
      tmp[k++] = q;
      q = q->p;
    }
    for (int i = (k - 1), _b = (0); i >= _b; i--) {
      push(tmp[i]);
    }
    while (v->p != pNull) {
      if (v->p->p == pNull) {
        rotate(v);
        break;
      }
      if ((v->p->p->l == v->p) == (v->p->l == v)) {
        rotate(v->p);
        rotate(v);
      } else {
        rotate(v);
        rotate(v);
      }
    }
  }
  inline pnode getComponentRoot(pnode v) {
    expose(v);
    while (v->l != pNull) {
      v = v->l;
      push(v);
    }
    splay(v);
    return v;
  }
  inline void expose(pnode v) {
    pnode root = pNull, s = v;
    while (v != pNull) {
      splay(v);
      if (v->r != pNull) {
        pnode w = v->r;
        v->r = w->p = pNull;
        push(w);
        while (w->l != pNull) {
          w = w->l;
          push(w);
        }
        splay(w);
        w->path = v;
        upd(v);
      }
      v->r = root;
      upd(root);
      upd(v);
      root = v;
      push(root);
      while (root->l != pNull) {
        root = root->l;
        push(root);
      }
      splay(root);
      v = v->path;
    }
    splay(s);
  }
  inline void makeRoot(pnode v) {
    expose(v);
    splay(v);
    v->rev = 1;
    push(v);
  }
  inline void link(pnode v1, pnode v2) {
    makeRoot(v1);
    v1->path = v2;
    expose(v2);
  }
  inline void cut(pnode v1, pnode v2) {
    makeRoot(v1);
    expose(v1);
    splay(v2);
    v2->path = pNull;
  }
};
int a, b, c, d, n, m, k;
LinkingCuttingTree<500002> q;
pair<int, int> mas[500002];
int pr[500002];
long long ans[500002];
const int V = 500001;
const int E = 500001;
int nx[E + 1], last[V + 1], ver[E + 1], edgesCount;
void dfs(int v, int h = 0) {
  mas[k++] = make_pair(h, v);
  for (int w = last[v]; w >= 0; w = nx[w]) {
    dfs(ver[w], h + 1);
  }
}
char buf[262145], *ch = buf;
char str[21];
inline char get_char() {
  if (*ch == 0) {
    ch = buf;
    fread(buf, sizeof(char), 262144, stdin);
  }
  return *(ch++);
}
inline void next_int(int &ans) {
  ans = 0;
  char ch;
  while ((ch = get_char()) < '0' || ch > '9')
    ;
  do {
    ans = ans * 10 + ch - '0';
  } while ((ch = get_char()) >= '0' && ch <= '9');
}
inline void addEdge(int v, int w) {
  ver[edgesCount] = w;
  nx[edgesCount] = last[v];
  last[v] = edgesCount++;
}
int main() {
  memset(last, -1, sizeof(last));
  next_int(n);
  for (int _n((n)-1), i(0); i <= _n; i++) {
    q.tr[i].l = q.tr[i].r = q.tr[i].p = q.tr[i].path = q.pNull;
  }
  int root = -1;
  for (int _n((n)-1), i(0); i <= _n; i++) {
    next_int(a);
    if (a == 0) {
      root = i;
      pr[i] = -1;
    } else {
      --a;
      addEdge(a, i);
      pr[i] = a;
    }
  }
  k = 0;
  dfs(root);
  sort(mas, mas + k);
  memset((ans), 0, sizeof(ans));
  for (int _n((n)-1), i(0); i <= _n; i++) {
    if (i && mas[i - 1].first == mas[i].first) continue;
    for (int _n(n - 1), j(i); j <= _n; j++) {
      if (mas[j].first != mas[i].first) break;
      int v = mas[j].second;
      if (pr[v] != -1) {
        int w = pr[v];
        q.link(q.tr + v, q.tr + w);
        q.expose(q.tr + w);
        q.tr[w].add += 1;
        q.push(q.tr + w);
      }
    }
    for (int _n(n - 1), j(i); j <= _n; j++) {
      if (mas[j].first != mas[i].first) break;
      int v = mas[j].second;
      if (pr[v] != -1) {
        int w = pr[v];
        q.expose(q.tr + w);
        q.push(q.tr + w);
        ans[v] = q.tr[w].sum;
      }
    }
  }
  for (int _n((n)-1), i(0); i <= _n; i++) {
    if (i) printf(" ");
    long long t = ans[i];
    int k = 0;
    while (t > 0) {
      str[k++] = t % 10 + '0';
      t /= 10;
    }
    if (!k) str[k++] = '0';
    str[k] = 0;
    reverse(str, str + k);
    printf("%s", str);
  }
  printf("\n");
}
