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

      

  • 相关阅读:
    ArrayList用法
    MessageBox
    将文本文件导入Sql数据库
    在桌面和菜单中添加快捷方式
    泡沫排序
    Making use of localized variables in javascript.
    Remove double empty lines in Visual Studio 2012
    Using Operations Manager Connectors
    Clear SharePoint Designer cache
    Programmatically set navigation settings in SharePoint 2013
  • 原文地址:https://www.cnblogs.com/bk-201/p/7445777.html
Copyright © 2011-2022 走看看