class Tree: def __init__(self,N,index=0): """N頂点(index, index+1, ..., N-1+index)の根付き木を生成する. """ self.N=N self.index=index self.parent=[-1]*(N+index) self.__mutable=True def vertex_exist(self,x): return self.index<=x>=1 i+=1 return x def lowest_common_ancestor(self,x,y): """頂点x,yの最小共通先祖(x,yに共通する先祖で最も深いもの)を求める. """ assert self.__after_seal_check(x,y) dd=self.vertex_depth(y)-self.vertex_depth(x) if dd<0: x,y=y,x dd=-dd y=self.upper(y,dd) if x==self.root: return x if x==y: return x d=self.vertex_depth(x) b=d.bit_length() X=self.upper_list for k in range(b-1,-1,-1): px=X[k][x];py=X[k][y] if px!=py: x=px;y=py return self.upper(x,1) def __degree_count(self): assert self.__after_seal_check() if hasattr(self,"deg"): return self.deg=[0]*(self.index+self.N) for v in range(self.index,self.index+self.N): d=len(self.children[v])+1 if d!=self.root: d-=1 self.deg[v]=d return def degree(self,v): """頂点vの次数を求める. """ assert self.__after_seal_check(v) if not hasattr(self,"deg"): self.__degree_count() return self.deg[v] def diameter(self): """木の直径を求める. """ assert self.__after_seal_check() from collections import deque def bfs(start): X=[-1]*(self.index+self.N) Q=deque([start]) X[start]=0 pa=self.parent ch=self.children while Q: x=Q.popleft() if X[pa[x]]==-1: Q.append(pa[x]) X[pa[x]]=X[x]+1 for y in ch[x]: if X[y]==-1: Q.append(y) X[y]=X[x]+1 y=max(range(self.index,self.index+self.N),key=lambda x:X[x]) return y,X[y] y,_=bfs(self.root) z,d=bfs(y) return y,z,d def path(self,u,v): """頂点u,v間のパスを求める. """ assert self.__after_seal_check(u,v) w=self.lowest_common_ancestor(u,v) pa=self.parent X=[u] while u!=w: u=pa[u] X.append(u) Y=[v] while v!=w: v=pa[v] Y.append(v) return X+Y[-2::-1] def is_brother(self,u,v): """2つの頂点u,vは兄弟 (親が同じ) か? """ assert self.__after_seal_check(u,v) if u==self.root or v==self.root: return False return self.parent[u]==self.parent[v] def is_ancestor(self,u,v): """頂点uは頂点vの先祖か? """ assert self.__after_seal_check(u,v) dd=self.vertex_depth(v)-self.vertex_depth(u) if dd<0: return False v=self.upper(v,dd) return u==v def is_descendant(self,u,v): """頂点uは頂点vの子孫か? """ assert self.__after_seal_check(u,v) return self.is_ancestor(v,u) def is_leaf(self,v): """頂点vは葉? """ return not bool(self.children[v]) def distance(self,u,v): """2頂点u,v間の距離を求める. """ assert self.__after_seal_check(u,v) dep=self.vertex_depth return dep(u)+dep(v)-2*dep(self.lowest_common_ancestor(u,v)) def __descendant_count(self): assert self.__after_seal_check() if hasattr(self,"des_count"): return if not hasattr(self,"tower"): self.depth_search(False) self.des_count=[1]*(self.index+self.N) pa=self.parent for T in self.tower[:0:-1]: for x in T: self.des_count[pa[x]]+=self.des_count[x] return def descendant_count(self,v): """頂点vの子孫の数を求める. """ assert self.__after_seal_check(v) self.__descendant_count() return self.des_count[v] def subtree_size(self,v): """頂点vを根とした部分根付き木のサイズを求める. """ return self.descendant_count(v) def preorder(self,v): """頂点vの行きがけ順を求める. """ assert self.__after_seal_check(v) if hasattr(self,"preorder_number"): self.preorder_number[v] from collections import deque Q=deque([self.root]) T=[-1]*(self.N+self.index) p=1 while Q: x=Q.popleft() T[x]=p p+=1 C=self.children[x] for y in C: Q.append(y) self.preorder_number=T return T[v] def dfs_yielder(self): """DFSにおける頂点の出入りをyieldする. (v,1): 頂点vに入る (v,0): 頂点vを出る """ assert self.__after_seal_check() #最初 yield (self.root,1) v=self.root ch=self.children pa=self.parent R=[-1]*self.index+[len(ch[x]) for x in range(self.index,self.index+self.N)] S=[0]*(self.index+self.N) while True: if R[v]==S[v]: #もし,進めないならば yield (v,0) #頂点vを出る if v==self.root: break else: v=pa[v] else: #進める w=v v=ch[v][S[v]] S[w]+=1 yield (v,1) def top_down(self): assert self.__after_seal_check() if not hasattr(self,"tower"): self.depth_search(False) for E in self.tower: for v in E: yield v def bottom_up(self): assert self.__after_seal_check() if not hasattr(self,"tower"): self.depth_search(False) for E in self.tower[::-1]: for v in E: yield v def tree_dp(self,calc,unit,f,g,Mode=False): """葉から木DPを行う. [input] calc:モノイドを成す2項演算 M x M -> M unit:Mの単位元 f,g: M -> M Mode: False->根の値のみ, True->全ての値 [補足] 頂点 v の子が x,y,z,...のとき, 更新式は dp[v]=g(f(x)*f(y)*f(z)*...) になる. """ data=[unit]*(self.index+self.N) pa=self.parent for x in self.bottom_up(): if x==self.root: break data[x]=g(data[x]) data[pa[x]]=calc(data[pa[x]],f(data[x])) if Mode: return data else: return data[self.root] #================================================== class Binary_Indexed_Tree(): def __init__(self,L,calc,unit,inv,index=1): """calcを演算とするN項のBinary Indexed Treeを作成 calc:演算(2変数関数,群) unit:群calcの単位元(xe=ex=xを満たすe) inv:群calcの逆元(1変数関数) """ self.calc=calc self.unit=unit self.inv=inv self.index=index N=len(L) d=max(1,(N-1).bit_length()) k=2**d X=[None]+[unit]*k self.num=k self.depth=d if L: for i in range(len(L)): p=i+1 while p<=k: X[p]=self.calc(X[p],L[i]) p+=p&(-p) self.data=X def index_number(self,k,index=1): """第k要素の値を出力する. k:数列の要素 index:先頭の要素の番号 """ return self.sum(k,k,index) def add(self,k,x,index=1,right=False): """第k要素にxを左から加え,更新を行う. k:数列の要素 x:更新後の値 index:先頭の要素の番号 right:「左から」が「右から」になる """ p=k+(1-index) while p<=self.num: if right==False: #左から self.data[p]=self.calc(x,self.data[p]) else: #右から self.data[p]=self.calc(self.data[p],x) p+=p&(-p) def update(self,k,x,index=1,right=False): """第k要素をxに変え,更新を行う. k:数列の要素 x:更新後の値 """ a=self.index_number(k,index) if right==False: #左から y=self.calc(x,self.inv(a)) else: #右から y=self.calc(self.inv(a),x) self.add(k,y,index,right) def sum(self,From,To,index=1): """第From要素から第To要素までの総和を求める. ※From!=1を使うならば,群でなくてはならない. From:始まり To:終わり index:先頭の要素の番号 """ alpha=max(1,From+(1-index)) beta=min(self.num,To+(1-index)) if alpha==1: return self.__section(beta) else: return self.calc(self.inv(self.__section(alpha-1)),self.__section(beta)) def __section(self,To): S=self.unit x=To while x>0: S=self.calc(self.data[x],S) x-=x&(-x) return S def all_sum(self): return self.data[-1] def __getitem__(self,index): if isinstance(index,int): return self.index_number(index,self.index) else: return [self.index_number(t,self.index) for t in index] def __setitem__(self,index,val): self.update(index,val,self.index) #================================================= from operator import add,neg N=int(input()) A=[-1]+list(map(int,input().split())) T=Tree(N) T.root_set(0) for i in range(1,N): T.parent_set(i,A[i]) T.seal() B=Binary_Indexed_Tree([0]*N,add,0,neg,0) X=0 for v,m in T.dfs_yielder(): if m==1: X+=B.sum(0,v,0) B.add(v,1,0) else: B.add(v,-1,0) print(X)