poj 3321 Apple Tree(建树 + 树状数组)

题意:给出一个树,每个树枝上都有一个苹果,给出N-1个树枝间的关系,然后给出M个操作,C表示树枝上原来有苹果的摘掉,没有的长出一个苹果,Q表示以这个树枝为根的所有子树的苹果树。

思路:这题的关键就是怎样将树上的各点映射到数组,先通过题目给出的条件建树,注意这题没有说是二叉树,可以用链表的方式建树,然后后序遍历这棵树,同时给各个树枝重新编号,是根的编号总是大于子树编号,然后在更新和查询这个子树时,就可以通过树状数组来实现了。

代码:

View Code
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <iostream>
#include <algorithm>
#include <queue>
#include <math.h>
#define N 100004
using namespace std ;
//存储M个条件
struct node
{
    int u ;
    int v ;
    int next ;
}p[N] ;
//后寻遍历存储节点
struct point
{
    int low ;
    int high ;
}d[N] ;

int head[N] , num , index ;
int app[N] , s[N] , n , m ;

void add( int x , int y )
{
    p[num].u = x ;
    p[num].v = y ;
    p[num].next = head[x] ;
    head[x] = num++ ;
}
//后序遍历
void dfs( int x )
{
    d[x].low = index ;
    if ( head[x] == -1 )
    {
        d[x].high = index++ ;
        return ;
    }
    for( int v = head[x] ; v != -1 ; v = p[v].next )
    {
        dfs( p[v].v );
    }
    d[x].high = index++ ;
}

int lowbit( int x )
{
    return x & ( -x );
}
//更新
void update( int x , int v )
{
    while ( x <= n )
    {
        s[x] += v ;
        x += lowbit( x );
    }
}
//查询
int sum ( int x )
{
    int ss = 0 ;
    while ( x > 0 )
    {
        ss += s[x] ;
        x -= lowbit( x );
    }
    return ss ;
}

int main()
{
    int i , x , y ;
    char c ;

    while( scanf( "%d" , &n ) != EOF )
    {
        num = 0 ;
        memset( head , -1 , sizeof( head ));
        for ( i = 0 ; i < n - 1 ; i++ )
        {
            scanf ( "%d%d" , &x , &y );
            add( x , y );
        }
        index = 1 ;
        dfs( 1 ) ;
        //初始时每个枝杈上都有一个苹果
        for( i = 0 ; i <= n ; i++ )
        app[i] = 1 ;
        for ( i = 1 ; i <= n ; i++ )
        s[i] = lowbit( i );
        scanf ( "%d" , &m );
        getchar();
        while( m-- )
        {
            scanf ( "%c%d" , &c , &x );
            getchar();
            if ( c == 'C')
            {
                int state = 1 ;
                if ( app[x] ) state = -1 ;
                app[x] = !app[x] ;
                update( d[x].high , state );
            }
            else
            {
                int ss = sum ( d[x].high ) - sum ( d[x].low - 1 );
                printf( "%d\n" ,ss ) ;
            }
        }
    }
    return 0 ;
}
原文地址:https://www.cnblogs.com/misty1/p/2616305.html