POJ 1321 Apple Tree【树状数组】

题意: 有一棵有 n 个节点并以 1 为根节点的树, 一开始每个节点有 1 个苹果,定义两种操作

          Q  i     询问以 i  为根节点的树上有多少个苹果。

          C  i     如果i 这个节点上有 1 个苹果就把它摘下,否在就在这个节点装上一个苹果。

分析: 可以把树上的每个节点对应到树状数组中, 对应的时候,越靠近根节点的节点管辖的数组区间范围越大, 可以利用深搜,根据访问的时间戳的顺序,依次为每个节点标记

         在树状数组中的下限 l[i], 因为要使得越靠近叶子节点的节点管辖区间越小,可以利用深搜回溯的特点,即越靠近叶子的节点,回溯到本身的时间差越短,这个时间差即为

         该节点覆盖的数组区间长度,因此每个节点覆盖的数组上限 h[i] = l[i] + 访问该节点与回溯到该节点的时间差

#include<stdio.h>
#include<string.h>
#define clr(x)memset(x,0,sizeof(x))
int n;
int a[100005];
int lowbit(int x)
{
    return (x)&(-x);
}
void add(int pos,int x)
{
    while(pos<=n)
    {
        a[pos]+=x;
        pos+=lowbit(pos);
    }
}
int sum(int pos)
{
    if(pos==0)
    return 0;
    int sum=0;
    while(pos>0)
    {
        sum+=a[pos];
        pos-=lowbit(pos);
    }
    return sum;
}
int l[100005];
int h[100005];
struct  node
{
    int to,next;
}e[100005];
int tot;
int head[100005];
void addedge(int s,int u)
{
    e[tot].to=u;
    e[tot].next=head[s];
    head[s]=tot++;
}
int t1,t2;
void dfs(int r)
{
    l[r]=t1++;
    int i,k;
    for(i=head[r];i;i=e[i].next)
    {
        k=e[i].to;
        dfs(k);
    }
    h[r]=t1-1;
}
int num[100005];
int main()
{
    char s[2];
    int i,m,f,son,p;
    while(scanf("%d",&n)!=EOF)
    {
        clr(a);
        clr(head);
        tot=1;
        t1=1;
        for(i=1;i<=n;i++)
        {
            add(i,1);
            num[i]=1;
        }
        for(i=0;i<n-1;i++)
        {
            scanf("%d%d",&f,&son);
            addedge(f,son);
        }
        dfs(1);
        scanf("%d",&m);
        while(m--)
        {
            scanf("%s%d",s,&p);
            if(*s=='Q')
                printf("%d\n",sum(h[p])-sum(l[p]-1));
            else 
            {
                if(num[p])
                {
                    num[p]=0;
                    add(l[p],-1);
                }
                else
                {
                    num[p]=1;
                    add(l[p],1);
                }
            }
        }
    }
    return 0;
}

 

posted @ 2012-08-07 13:16  'wind  阅读(177)  评论(0编辑  收藏  举报