zoukankan      html  css  js  c++  java
  • 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;
    }
    

      

  • 相关阅读:
    yii2框架随笔27
    yii2框架随笔26
    yii2框架随笔25
    yii2框架随笔24
    yii2框架随笔23
    yii2框架随笔21
    yii2框架随笔20
    yii2框架随笔19
    yii2源码学习笔记(十五)
    yii2源码学习笔记(十四)
  • 原文地址:https://www.cnblogs.com/liulangye/p/2592965.html
Copyright © 2011-2022 走看看