zoukankan      html  css  js  c++  java
  • 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 ;
    }
  • 相关阅读:
    mina中的发送延时
    微服务理论之五:微服务架构 vs. SOA架构
    同步
    JAVA中线程同步的方法(7种)汇总
    http连接管理
    MySQL存储引擎比较
    ZAB与Paxos算法的联系与区别
    syslog之二:syslog协议及rsyslog服务全解析
    微服务理论之六:ESB与SOA的关系
    DBCP连接池原理分析及配置用法
  • 原文地址:https://www.cnblogs.com/misty1/p/2616305.html
Copyright © 2011-2022 走看看