POJ 3321 Apple Tree(dfs序+BIT)

Description
给你一颗树,最初每个节点上都有一个苹果,有两种操作:修改(即修改某一个节点,修改时这一个节点苹果从有到无,或从无到有)和查询(查询某一个节点他的子树上有多少个苹果)
Input
第一行为树的节点数n,之后n-1行每行两个整数u和v表示树上有一条从u到v的边,之后一行为一个整数m表示操作数,最后m行每行一个操作,Q x表示查询x所在子树的苹果总数,C x表示对x节点的苹果进行操作
Output
对于每次查询,输出x所在子树的苹果总数
Sample Input
3
1 2
1 3
3
Q 1
C 2
Q 1
Sample Output
3
2
Solution
首先对这棵树做一遍dfs搜索建立dfs序列,每个节点都赋一个左值和右值表示其管辖范围,每次查询只需查询sum(1,r)和sum(1,l-1)做差即可
Code

#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<queue>
#include<stack>
#include<vector>
#include<string>
#include<set>
#include<map>
using namespace std;
#define maxn 111111
int n,m;
int b[maxn],l[maxn],r[maxn],cnt[maxn],order;
vector< vector<int> >tree(maxn);
void init()//初始化 
{
    order=1;
    memset(l,0,sizeof(l));
    memset(r,0,sizeof(r));
    for(int i=0;i<maxn;i++)
        tree[i].clear();
}
void dfs(int u)
{
    l[u]=order;
    for(int i=0;i<tree[u].size();i++)
    {
        order++;
        dfs(tree[u][i]);
    }
    r[u]=order;
}
int lowbit(int x)
{
    return x&(-x);
}
void update(int x,int v)
{
    while(x<=n)
    {
        b[x]+=v;
        x+=lowbit(x);
    }
}
int getsum(int x)
{
    int ans=0;
    while(x>0)
    {
        ans+=b[x];
        x-=lowbit(x);
    }
    return ans;
}
int main()
{
    while(~scanf("%d",&n))
    {
        init();
        for(int i=1;i<n;i++)
        {
            int u,v;
            scanf("%d%d",&u,&v);
            tree[u].push_back(v);//建边 
        }
        for(int i=1;i<=n;i++)
        {
            cnt[i]=1;//每个节点初始状态都有一个苹果 
            update(i,1);
        }
        dfs(1);//建立dfs序列 
        scanf("%d",&m);
        while(m--)
        {
            char op[3];
            int tar;
            scanf("%s%d",op,&tar);
            if(op[0]=='C')//改变该节点的状态 
            {
                if(cnt[tar])//有苹果则摘掉 
                    update(l[tar],-1);
                else//没苹果则添一个 
                    update(l[tar],1);
                cnt[tar]=!cnt[tar];
            }
            else if(op[0]=='Q')//查询该节点子树的苹果总数 
                printf("%d\n",getsum(r[tar])-getsum(l[tar]-1));
        }
    }
    return 0;
} 

你可能感兴趣的:(POJ 3321 Apple Tree(dfs序+BIT))