POJ 3321 apple tree(树形数组)

题意:

一棵具有n个节点的树,一开始,每个节点上都有一个苹果。现在给出m组动态的操作:

(C,i)是摘掉第i个节点上面的苹果(若苹果不存在,则为加上一个苹果),(Q,i)是查询以第i个节点为根的子树有几个苹果(包括第i个节点)。

参考了:http://www.cnblogs.com/ybrbupt/archive/2011/09/24/2189519.html

思路:

树形数组,但是问题的关键是,如何把树的各个节点映射到数组中去,然后再应用树形数组的优势去解决?

dfs()函数中的代码就十分精妙的体现了如何去映射。相当于把每个节点重新编号了。

初始化要注意,因为开始默认每个节点都会有个苹果,所以先要对c[]数组进行初始化,c[]对应的线性数组每个元素都是1,所以c[i]=i&-i就行了

#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <vector>

using namespace std;

const int MAXN = 100010;

vector<vector<int>> G(MAXN);
bool vis[MAXN];
bool apple[MAXN];
int high[MAXN], low[MAXN];
int c[MAXN];
int n, count;

inline int lowbit(int x)
{
    return x & (-x);
}

void dfs(int u)
{
    vis[u] = true;
    low[u] = count;  // 节点u为根节点的子树映射到数组内的下届
    
    for (int i = 0; i < G[u].size(); ++i)
    {
        int v = G[u][i];
        if (!vis[v])
            dfs(v);
    }
    high[u] = count++; // 节点u为根节点的子树映射到数组内的上界
}

int sum(int p)
{
    int ans = 0;
    for (int i = p; i > 0; i -= lowbit(i))
        ans += c[i];
    return ans;
}

inline void update(int p)
{
    int d;
    if (apple[p])
        d = -1;
    else
        d = 1;
    apple[p] ^= true;
    for (int i = p; i <= n; i += lowbit(i))
        c[i] += d;
}

int main()
{
    scanf("%d", &n);
    for (int i = 1; i <= n; ++i)
        c[i] = lowbit(i), apple[i] = true, vis[i] = false;

    for (int i = 1; i < n; ++i)
    {
        int a, b;
        scanf("%d %d", &a, &b);
        G[a].push_back(b);
        G[b].push_back(a);
    }
    count = 1;
    dfs(1);

    int m;
    scanf("%d", &m);
    for (int i = 1; i <= m; ++i)
    {
        char s[10];
        int u;
        scanf("%s %d", s, &u);
        if (s[0] == 'Q')
            printf("%d\n", sum(high[u]) - sum(low[u]-1));
        else if (s[0] == 'C')
            update(high[u]);
    }
    return 0;
}
-------------------------------------------------------

kedebug

Department of Computer Science and Engineering,

Shanghai Jiao Tong University

E-mail: kedebug0@gmail.com

GitHub: http://github.com/kedebug

-------------------------------------------------------

原文地址:https://www.cnblogs.com/kedebug/p/2763460.html