zoukankan      html  css  js  c++  java
  • POJ3321 Apple Tree

    题目大意

    有一颗苹果树,它有N个树叉,每个树叉最开始的时候都结了一个苹果,有时卡卡会从树上把某个苹果摘下来,有时没结苹果的树叉上又会长出苹果来,卡卡有时还想知道某个子树的总苹果数量有多少

    题解

    题目也是要求实现单点加减,区间求和的功能,赤裸裸的树状数组呀,不过此题给出的不是一个线性的序列,而是树形的,因此我们需要先进行预处理,把树转换为线性序列。用邻接表建立好树,然后对树进行重新编号,这个可以用DFS来实现,每个节点记录第一次访问和最后一次访问时的编号,假设为l和r,那么区间[l,r]之间的所有编号是以此节点为根节点的子树的各个节点的编号,这样就把树转化为线性结构了,之后就是用树状数组来处理了

    代码:

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #define MAXN 100005
    using namespace std;
    typedef struct
    {
        int adv;
        int next;
    } NODE;
    NODE edg[2*MAXN];
    int head[MAXN],c[MAXN],low[MAXN],high[MAXN];
    bool visit[MAXN];
    int n,m,k,step=0;
    int lowbit(int x)
    {
        return x&-x;
    }
    int sum(int x)
    {
        int ret=0;
        while(x>0)
        {
            ret+=c[x];
            x-=lowbit(x);
        }
        return ret;
    }
    void add(int x,int d)
    {
        while(x<=n)
        {
            c[x]+=d;
            x+=lowbit(x);
        }
    }
    void addege(int u,int v)
    {
        edg[k].adv=v;
        edg[k].next=head[u];
        head[u]=k++;
    }
    void dfs(int u)
    {
        int i;
        low[u]=++step;
        visit[u]=true;
        for(i=head[u]; i!=-1; i=edg[i].next)
            if(!visit[edg[i].adv])
                dfs(edg[i].adv);
        high[u]=step;
    }
    int main(void)
    {
        int i,u,v;
        bool f[MAXN];
        char ch;
        memset(head,-1,sizeof(head));
        memset(visit,false,sizeof(visit));
        memset(f,false,sizeof(f));
        scanf("%d",&n);
        k=1;
        for(i=1; i<n; i++)
        {
            scanf("%d%d",&u,&v);
            addege(u,v);
            add(i,1);
        }
        add(i,1);
        dfs(1);
        scanf("%d",&m);
        while(m--)
        {
            getchar();
            scanf("%c%d",&ch,&i);
            if(ch=='C')
            {
                if(!f[i])
                {
                    add(low[i],-1);
                    f[i]=true;
                }
                else
                {
                    add(low[i],1);
                    f[i]=false;
                }
            }
            else
                printf("%d\n",sum(high[i])-sum(low[i]-1));
        }
        return 0;
    }

     

     

     

  • 相关阅读:
    学习ASP.NET Web API框架揭秘之“HTTP方法重写”
    学习、摘录、目标——学习任务
    ASP.NET Core学习零散记录
    通过Nginx实现负载均衡
    通过IIS共享文件夹来实现静态资源"本地分布式"部署
    python2.7 django 错误汇总
    【心得】算法练习
    【数据结构】思维导图
    【算法】思维导图
    记录一次面试中二分查找的算法题
  • 原文地址:https://www.cnblogs.com/zjbztianya/p/3036884.html
Copyright © 2011-2022 走看看