zoukankan      html  css  js  c++  java
  • 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("") ;
       }
    }
    
  • 相关阅读:
     随机选择数据库记录的方法
    交叉查询
    Delphi编辑器颜色设置
    Delphi Dll中多线程无法使用Synchronize同步的解决方法(转)
    Delphi FTP例子源码
    DELPHI之备忘四
    界面美化代码
    使Form响应滚轮事件
    配色卡
    Delphi http传输备忘
  • 原文地址:https://www.cnblogs.com/20120125llcai/p/3355986.html
Copyright © 2011-2022 走看看