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;
}

  

原文地址:https://www.cnblogs.com/liulangye/p/2592965.html