POJ 3321 Apple Tree (树状数组)

http://poj.org/problem?id=3321

题意:给出一颗苹果树,开始每个树叉上都有 一个苹果,苹果树总是以1为根,Q 1表示1树枝上有多少苹果,C 2表示更新树枝2上的苹果,以前有苹果变成没有,以前没有变成有,树杈上的苹果数不超过1

分析:插入,删除频繁,还需要算和,10^5的数据量,用线段树或树状数组,但是给出的是一棵树,不在一条线上。。。有时候不能看出什么是区间,就要仔细观察,造出“区间”,

如果从1根节点出发,dfs遍历树一遍,那遍历每个节点的时间是一条线,把时间划成区间。。。每个节点有两个时间戳,low[]表示开始时间,high[]表示结束时间。那么这个树枝上苹果的个数就是开始时间和结束时间之间的苹果

代码:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#define nMAX 100005
using namespace std;
int low[nMAX],high[nMAX],c[nMAX],head[nMAX];
int n,m,s_edge,times;
bool vs[nMAX],has[nMAX];
struct Edge
{
    int u,v,nxt;
}edge[nMAX*2];
struct Tree
{
    int l,r;
}tree[nMAX*3+100];
void addedge(int u,int v)
{
    s_edge++;
    edge[s_edge].v=v;
    edge[s_edge].nxt=head[u];
    head[u]=s_edge;
}
void dfs(int u)
{
    low[u]=++times;
    vs[u]=1;
    for(int e=head[u];e;e=edge[e].nxt)
    {
        int v=edge[e].v;
        if(!vs[v]) dfs(v);
    }
    high[u]=times;
}

int lowbit(int x)
{
    return x&(-x);
}
void add(int i ,int num)
{
    while(i<=n)
    {
        c[i]+=num;
        i+=lowbit(i);

    }
}
int sum(int i)
{
    int ans=0;
    while(i>=1)
    {
        ans+=c[i];
        i-=lowbit(i);
    }
    return ans;

}
int main()
{
    char ch;
    int i,j,k;
    while(~scanf("%d",&n))
    {
        memset(head,0,sizeof(head));
        s_edge=0;
        for(k=1;k<n;k++)
        {
            scanf("%d%d",&i,&j);
            addedge(i,j);
            addedge(j,i);
        }
        memset(c,0,sizeof(c));
        for(i=1;i<=n;i++)//每个树枝都有apple
            add(i,1);
        times=0;
        memset(vs,0,sizeof(vs));
        dfs(1);
        memset(has,0,sizeof(has));//都有
        scanf("%d",&m);
        while(m--)
        {
            getchar();
            scanf("%c%d",&ch,&i);
            if(ch=='Q')
            {
                int ans=sum(high[i])-sum(low[i]-1);
                printf("%d\n",ans);
            }
            else
            {
                if(!has[i]){add(low[i],-1);has[i]=1;}
                else {add(low[i],1);has[i]=0;}

            }
        }
    }
    return 0;
}

  

posted @ 2012-08-17 20:24  快乐.  阅读(171)  评论(0编辑  收藏  举报