#!/usr/bin/python # -*- coding: utf-8 -*- # import from sys import stdin, setrecursionlimit setrecursionlimit(10**8) # def def int_map(): return map(int,input().split()) def int_list(): return ['Null']+list(map(int,input().split())) # 整数のリストのリスト:N+1行のリスト(各行のリストは同じ長さでなくてよい.) def int_mtx(N): x = [['Null']+list(map(int, stdin.readline().split())) for _ in range(N)] x.insert(0,['Null']) return x # 文字のリストのリスト:N+1行のリスト(各行のリストは同じ長さでなくてよい.) # AAAAA # BBBBB # CCCCC # のような標準入力を # '0AAAAA' # '0BBBBB' # '0CCCCC' # と受け取る def str_mtx(N): x = ['0'+stdin.readline()[:-1] for _ in range(N)] x.insert(0,'0') return x # 文字のリストのリスト:N+1行のリスト(各行のリストは同じ長さでなくてよい.) # AAAAA XXXXX # BBBBB YYYYY # CCCCC ZZZZZ # のような標準入力を # [[['0'],[AAAAA],[XXXXX]], # [['0'],[BBBBB],[YYYYY]], # [['0'],[CCCCC],[ZZZZZ]] ] # と受け取る def str_list(N): x = [['0']+list(map(str, stdin.readline().split())) for _ in range(N)] x.insert(0,['0']) return x # 高さH+1, 幅W+1, のゼロ行列の作成 def zero_mtx(H,W): x = [[0]*(W+1) for i in range(H+1)] return x # リストをスペースで分割する(先頭を省く) def print_space(l): return print(" ".join([str(x) for x in l[1:]])) # ゼロインデックスの場合 # 整数のリストのリスト:N行のリスト(各行のリストは同じ長さでなくてよい.) def int_mtx_0(N): x = [list(map(int, stdin.readline().split())) for _ in range(N)] return x # ゼロインデックスの場合 # 文字のリストのリスト:N+1行のリスト(各行のリストは同じ長さでなくてよい.) def str_mtx_0(N): x = [list(stdin.readline()[:-1]) for _ in range(N)] return x # ゼロインデックスの場合 # リストをスペースで分割する(先頭を省かない) def print_space_0(l): return print(" ".join([str(x) for x in l])) # ゼロインデックスの場合 # 高さH, 幅W, のゼロ行列の作成 def zero_mtx_0(H,W): x = [[0]*W for i in range(H)] return x def int_list_0(): return list(map(int,input().split())) ## インポート # from collections import deque # 順列に使う # import itertools # 最大公約数などに使う # import math # リストの要素の数をdict形式で # import collections # 二次元配列のコピーを作りたいとき # a_copy = deepcopy(a) # from copy import deepcopy from collections import deque, defaultdict # 絶対に有効化する import pypyjit pypyjit.set_param('max_unroll_recursion=-1') N = int(input()) # UV については無向辺のつもりで書けば良い cccc = int_list_0() UV = [] for i in range(N-1): UV.append([i+1,cccc[i]]) root_id = 0 G = [[] for _ in range(N)] for ui,vi in UV: G[ui].append(vi) G[vi].append(ui) # Euler Tour Technique S = [] FS = [0]*N AS = defaultdict(list) depth = [0]*N def dfs(v, p, d): depth[v] = d FS[v] = len(S) AS[v].append(len(S)) S.append(v) for w in G[v]: if w == p: continue dfs(w, v, d+1) AS[v].append(len(S)) S.append(v) dfs(root_id, -1, 0) # Sparse Table L = len(S) lg = [0]*(L + 1) for i in range(2, L+1): lg[i] = lg[i >> 1] + 1 st = [None]*(lg[L] + 1) st0 = st[0] = S b = 1 for i in range(lg[L]): st0 = st[i+1] = [p if depth[p] <= depth[q] else q for p, q in zip(st0, st0[b:])] b <<= 1 # LCA O(1) def LCA(u, v): x = FS[u]; y = FS[v] if x > y: x, y = y, x l = lg[y - x + 1] px = st[l][x]; py = st[l][y - (1 << l) + 1] return px if depth[px] <= depth[py] else py class SegTree: def __init__(self, A, SegType): if SegType == "min": self.X_f = min self.X_unit = float('inf') elif SegType == "max": self.X_f = max self.X_unit = -float('inf') elif SegType == "sum": def segfunc(x, y): return x+y self.X_f = segfunc self.X_unit = 0 elif SegType == "pro": def segfunc(x, y): return x*y self.X_f = segfunc self.X_unit = 1 elif SegType == "xor": def segfunc(x, y): return x^y self.X_f = segfunc self.X_unit = 0 elif SegType == "gcd": from math import gcd self.X_f = gcd self.X_unit = 0 elif SegType == "lcm": from math import gcd def lcm(a,b): return a//gcd(a,b)*b self.X_f = lcm self.X_unit = 1 self.N = len(A) self.X = [self.X_unit] * (self.N + self.N) self.build(A) def leaf(self): return self.X[self.N:] def build(self, seq): for i, x in enumerate(seq, self.N): self.X[i] = x for i in range(self.N - 1, 0, -1): self.X[i] = self.X_f(self.X[i << 1], self.X[i << 1 | 1]) def set_val(self, i, x): i += self.N self.X[i] = x while i > 1: i >>= 1 self.X[i] = self.X_f(self.X[i << 1], self.X[i << 1 | 1]) def add_val(self, i, x): i += self.N self.X[i] += x while i > 1: i >>= 1 self.X[i] = self.X_f(self.X[i << 1], self.X[i << 1 | 1]) def fold(self, L, R): L += self.N R += self.N vL = self.X_unit vR = self.X_unit while L < R: if L & 1: vL = self.X_f(vL, self.X[L]) L += 1 if R & 1: R -= 1 vR = self.X_f(self.X[R], vR) L >>= 1 R >>= 1 return self.X_f(vL, vR) A = [0]*len(S) SegType = "sum" seg = SegTree(A, SegType) ans = 0 for i in reversed(range(N)): l = AS[i][0] r = AS[i][-1] ans += seg.fold(l,r+1) seg.set_val(AS[i][0],1) print(ans)