zoukankan      html  css  js  c++  java
  • POJ 3321 Apple Tree 树状数组+dfs序

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

    题意:给出一个苹果树,开始每个节点都有一个苹果,有2个操作

    C:有苹果就吃掉,没有就会长出一个苹果

    Q:查询包括x的子树上苹果的个数

    这个题目的关键就是怎么把它从一颗树转化成一个数组

    可以用dfs序重新编号,保存节点所维护的区间,然后用树状数组可以解决了

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<string>
    #include<cmath>
    #include<algorithm>
    #include<vector>
    #include<queue>
    #include<stack>
    #include<map>
    #include<set>
    using namespace std;
    const int N=1e5+5;
    struct p
    {
        int to,nextt;
    };
    p a[N*2];
    int tot,n;
    int f[N],l[N],r[N],bit[N];
    bool vis[N];
    void addedge(int u,int v)
    {
        a[tot].to=v;
        a[tot].nextt=f[u];
        f[u]=tot++;
    }
    void dfs(int x)
    {
        tot++;
        l[x]=tot;
        vis[x]=1;
        for(int i=f[x];i!=-1;i=a[i].nextt)
            if (!vis[a[i].to])
                dfs(a[i].to);
        r[x]=tot;
    }
    void add(int i,int x)
    {
        while(i<=n)
        {
            bit[i]+=x;
            i+=i&-i;
        }
    }
    int sum(int i)
    {
        int s=0;
        while(i>0)
        {
            s+=bit[i];
            i-=i&-i;
        }
        return s;
    }
    int main()
    {
        while(scanf("%d",&n)!=EOF)
        {
            int x,y;
            tot=0;
            memset(f,-1,sizeof(f));
            for(int i=1;i<n;i++)
            {
                scanf("%d%d",&x,&y);
                addedge(x,y);
                addedge(y,x);
            }
            tot=0;
            memset(vis,0,sizeof(vis));
            dfs(1);
            memset(bit,0,sizeof(bit));
            for(int i=1;i<=n;i++)
                add(i,1);
            memset(vis,1,sizeof(vis));
            int m;
            char c;
            scanf("%d",&m);
            while(m--)
            {
                scanf(" %c%d",&c,&x);
                if (c=='Q')
                    printf("%d
    ",sum(r[x])-sum(l[x]-1));
                else
                {
                    if (vis[x])
                    {
                        vis[x]=0;
                        add(l[x],-1);
                    }
                    else
                    {
                        vis[x]=1;
                        add(l[x],1);
                    }
                }
            }
        }
        return 0;
    }
    

      

  • 相关阅读:
    关联规则算法---Eclat算法
    Apriori算法第二篇----详细分析和代码实现
    scrapy框架初识
    git入门
    phantomjs的和谷歌浏览器的简单使用
    selenium模块的而简单使用
    代理ip的使用以及多进程爬取
    爬虫之re块解析
    爬虫初识和request使用
    xpath的基础使用
  • 原文地址:https://www.cnblogs.com/bk-201/p/7445777.html
Copyright © 2011-2022 走看看