Easy Tree Problem
A tree structure is very special structure, there is exactly one path connecting each pair of nodes.
Now, given a tree structure, which has N nodes(conveniently labeled from 1 to N). And the root of the tree is always labeled with 1. You are to write a program to figure out that, for every node V in the tree, how many nodes there are in the sub-tree rooted by V and it’s label number is larger than the label number of V.
For the example above:
Ans[1] = 6,Ans[2] = 1,Ans[3] = 2,Ans[4] = 0,
Ans[5] = 0, Ans[6] = 0,Ans[7] = 0
Input
There are multiple cases.The first line is an integer T representing the number of test cases.The following lines every tow lines representing a test case. For each case there are exactly two lines:The first line with a single integer N(1 <= N <= 200000), representing the size of tree.The second line with N – 1 numbers: P[2], P[3], ……P[n]. (1 <= P[i] <= N),Which mean the father node of node i is P[i].It is guaranteed that the input data is a tree structure and has 1 as root.
Output
For each test case, output a line of N numbers in the following format:
Case #C: Ans[1] Ans[2] Ans[3] …… Ans[N]
Sample Input
2
7
1 1 3 2 1 3
4
1 2 3
Sample Output
Case #1: 6 1 2 0 0 0 0
Case #2: 3 2 1 0
Source
The 5th ACM Programming Contest of HUST
// 对每个父亲节点 给他左边界标号 len , 有边界 为len+n ;n 为他的儿子数 // 对于他的儿子标号为len+1,len+2...len+n // 然后从最大节点开始查找答案,然后更新树状数组 #include<cmath> #include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<queue> #define maxn 50003 #define LL long long using namespace std ; int head[maxn] , next1[maxn] , to[maxn] ; int ans[maxn] , len ,xt[maxn+10]; int L[maxn] , R[maxn] ; int low( int x ) { return x&(-x) ; } void update( int x ) { while( x <= maxn-2 ) { xt[x]++ ; x += low(x) ; } } int sum( int x ) { int ans = 0; while( x > 0 ) { ans += xt[x] ; x -= low(x) ; } return ans ; } void dfs(int u ) { int i , v ; L[u] = ++len ; for( i = head[u] ; i != -1 ;i = next1[i]) { dfs(to[i]) ; } R[u] = len ; } int main(){ int i , j , case1 = 0, T , top ; int n ; cin >> T ; while(T--) { scanf("%d" , &n ) ; memset(ans,0,sizeof(ans)) ; memset(head,-1,sizeof(head)) ; top = len = 0 ; for( i = 2 ; i <= n ;i++ ) { scanf("%d" , &j ) ; next1[top] = head[j] ; to[top] = i ;head[j] = top++ ; } memset(xt,0,sizeof(xt)) ; dfs(1) ; for( i = n ; i >= 1 ;i-- ) { ans[i] = sum(R[i]) - sum(L[i]-1) ; update(L[i]) ; } printf("Case #%d:",++case1 ) ; for( i = 1 ; i <= n ;i++ ) printf(" %d",ans[i]) ; puts("") ; } }