poj 3321 Apple Tree

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

题目大意:

给你N个点组成的树 每个点初始化为1 有两种操作

C x:改变点的值 是1变0 是0变1

Q x:问以x为根的子树上点值的和

思路:

主要是把树映射到树状数组中

一遍dfs把点重新编号 low和high low表示刚搜到此点时的计数,high是搜玩其子树内所有节点后回来的计数编号

比如说又n个点那么根节点1的low=1,high=2*n

这样就映射到树状数组中啦。

代码及其注释:

#include<iostream>

#include<cstdio>

#include<cstring>

#include<string>

#include<cmath>

#include<queue>

#include<algorithm>

#include<stack>



using namespace std;



const int N=100010;

struct node

{

    struct tt *next;

}mem[N];

struct tt

{

    struct tt *next;

    int j;

};

int n,I;//n is the number of apples I 是全局计数

int c[N*2];

int high[N];

int low[N];

bool visited[N];

int apple[N];//某个点是否有苹果

void build(int i,int j)//建树

{

    struct tt *t=new tt;

    t->j=j;

    t->next=mem[i].next;

    mem[i].next=t;

}

void dele()//一定的清理

{

    for(int i=1;i<=n;++i)

    mem[i].next=NULL;

}

int lowbit(int x)

{

    return x&(-x);

}

void Add(int x,int k)

{

    for(int i=x;i<=2*n;i+=lowbit(i))

    {

        c[i]+=k;

    }

}

int Sum(int x)

{

    int sum=0;

    for(int i=x;i>0;i-=lowbit(i))

    {

        sum+=c[i];

    }

    return sum;

}

void dfs(int x)//深搜 计数

{

    visited[x]=true;

    ++I;

    low[x]=I;

    struct tt *t=new tt;

    t=mem[x].next;

    while(t!=NULL)

    {

        if(visited[t->j]==false)

        {

            dfs(t->j);

        }

        t=t->next;

    }

    ++I;

    high[x]=I;



}

int main()

{

   int m;

   while(scanf("%d",&n)!=EOF)

   {

       memset(c,0,sizeof(c));

       for(int i=1;i<n;++i)

       {

           int l,r;

           scanf("%d %d",&l,&r);

           build(l,r);

           build(r,l);

       }

       I=0;

       memset(visited,false,sizeof(visited));

       dfs(1);

       for(int i=1;i<=n;++i)

       {

           apple[i]=1;

       }

       for(int i=1;i<=2*n;++i)

       {

           Add(i,1);//初始化树状数组

       }

       scanf("%d",&m);

       while(m--)

       {

           char c;

           int k;

           getchar();

           scanf("%c %d",&c,&k);

           if(c=='Q')

           {

               printf("%d\n",(Sum(high[k])-Sum(low[k]-1))/2);

           }else

           {

               if(apple[k]==1)

               {

                   apple[k]=0;

                   Add(low[k],-1);

                   Add(high[k],-1);

               }

               else

               {

                   apple[k]=1;

                   Add(low[k],1);

                   Add(high[k],1);

               }

           }

       }

       dele();

   }

   return 0;

}

  

你可能感兴趣的:(apple)