POJ3321 Apple Tree(DFS序 + 树状数组)

题目链接:传送门

题意:

给定一颗树,初始的时候每个节点的值为1。

修改操作:C X 如果点X的值为1则变成0,如果点X的值为0则变成1.

查询操作:Q X 查询X这个节点以及以它为根的子树的所有节点的和。

分析:

DFS序:根据dfs的时候节点进栈与出栈的时间点。in[u]/out[u]代表点u进/出栈的时间,那么(in[u],out[u])之间的节点就是点u子树上的节点。

我们根据DFS序来维护一个树状数组就可以了。

代码如下:

#include <cstring>
#include <algorithm>
#include <cstdio>
#include <vector>
using namespace std;

const int maxn = 1e5+10;

int has[maxn];
int n;

struct Tree{
    struct nod{
        int to,next;
    }edge[maxn];
    int in[maxn],out[maxn],tt;
    int head[maxn],ip;
    void init(){
        tt=0,ip=0;
        memset(head,-1,sizeof(head));
    }
    void add(int u,int v){
        edge[ip].to= v;
        edge[ip].next = head[u];
        head[u]= ip++;
    }
    void dfs(int u){
        in[u]=++tt;
        for(int i=head[u];i!=-1;i=edge[i].next){
            int v = edge[i].to;
            dfs(v);
        }
        out[u]=tt;
    }
}G;

struct BIT {
    int sum[maxn];
    void init(){
        memset(sum,0,sizeof(sum));
    }
    int lowbit(int x) {
        return x&(-x);
    }
    void update(int pos,int x){
        while(pos<=n){
            sum[pos]+=x;
            pos+=lowbit(pos);
        }
    }
    int query(int pos){
        int ans = 0;
        while(pos>0){
            ans+=sum[pos];
            pos-=lowbit(pos);
        }
        return ans;
    }
}T;

int main() {
    while(~scanf("%d",&n)){
        G.init();
        T.init();
        for(int i=1;i<n;i++){
            int u,v;
            scanf("%d%d",&u,&v);
            G.add(u,v);
        }
        G.dfs(1);
        for(int i=1;i<=n;i++){
            T.update(G.in[i],1);
            has[i]=1;
        }
        int x,m;
        scanf("%d",&m);
        char s[2];
        while(m--){
            scanf("%s%d",s,&x);
            if(s[0]=='C'){
                if(has[x])
                    T.update(G.in[x],-1);
                else
                    T.update(G.in[x],1);
                has[x]^=1;
            }
            else
                printf("%d\n",T.query(G.out[x])-T.query(G.in[x]-1));
        }
    }
    return 0;
}

你可能感兴趣的:(POJ3321 Apple Tree(DFS序 + 树状数组))