Apple Tree----树的遍历和树状数组的结合

题目链接:http://acm.nyist.net/JudgeOnline/problem.php?pid=231

解题思路:苹果完全可以倒过来看做一棵树(注意不一定是二叉树),求一个分叉上面的苹果数量,就是求颗子树有多少 节点,对于一个树进行一次遍历后,所有节点都已经访问过了,将遍历序列使用树状数组记录下来的,只需一个 start数组和end数组记录每个子树的开始和结束在序列中的位置,就可以快速的得到子树的节点数量。

本题只需对数进行先根遍历,记录树状数组和开始结束位置,再使用一个has数组对每一个节点标记是否有苹 果。对于每次改变状态,使用树状数组的modify函数对所有涉及到的位置进行改变即可。

代码附上:

#include<stdio.h>
#include<vector>
#include<string.h>
using namespace std;
int nCount = 0;
vector<int> G[100005];
int C[100005], has[100005];
int Start[100005], End[100005];
void DFS(int x) {
    Start[x] = ++nCount; //标记开始位置
    for(int i = 0; i < G[x].size(); i++) { 
       DFS(G[x][i]); //标记结束位置
    } 
    End[x] = nCount;
}
int lowbit(int x) {
	return x&(-x);
}
int Sum(int x) {
    int nSum = 0;
    while(x > 0) {
        nSum += C[x];
        x -= lowbit(x);
    }
    return nSum;
}    
void Modify(int x, int val) {
    while(x <= nCount) {
        C[x] += val;
        x += lowbit(x);
    }    
} 
int main() {
//	freopen("data.in", "r", stdin);
    int n, m;
	int a,b;
	scanf("%d", &n);
    for(int i = 1;i < n; i++) {   
        scanf("%d%d", &a, &b);
        G[a].push_back(b);
    }    
    nCount = 0; DFS(1);
    //每个节点一个苹果,树状数组数值即lowbit 
    for(int i = 1; i <= nCount; i++) {
        C[i] = lowbit(i);
    }
    memset(has, 1, sizeof(has));
    scanf("%d", &m);
    for(int i = 0;i < m; i++) {
        char cmd[5];
        scanf("%s%d", cmd, &a);
        if(cmd[0] == 'C') {
            if(has[a]) { 	//如果等于说明该节点有苹果,应该摘取 
                has[a] = 0;
				Modify(Start[a], -1);
                
            } else {
            	has[a] = 1;
                Modify(Start[a], 1);
            }    
        } else {
            printf("%d\n",Sum(End[a]) - Sum(Start[a]-1));
        }        
    }
    return 0;
        
}    



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值