POJ3321 Apple Tree(树状数组)

先做一次dfs求得每个节点为根的子树在树状数组中编号的起始值和结束值,再树状数组做区间查询 与单点更新。


#include<cstdio>
#include<iostream>
#include<cstdlib>
#include<cstring>
#include<string>
#include<algorithm>
#include<map>
#include<queue>
#include<vector>
#include<cmath>
#include<utility>
using namespace std;
typedef long long LL;
const int N = 100008, INF = 0x3F3F3F3F;
#define MS(a, num) memset(a, num, sizeof(a))
int leftid[N], rightid[N];
struct Node{
    int to,next;
}edge[2 * N];
int head[N],tot;
void init(){
    memset(head, -1sizeof(head));
    tot = 0;
}
inline void addedge(int u, int to){
    edge[tot].to=to;
    edge[tot].next=head[u];
    head[u]=tot++;
}
int n, m;
bool sta[N];
int C[N];
inline int lowbit(int x){
    return x&-x;
}
inline void add(int x, int val){
    for(int i=x;i<=n;i+=lowbit(i)){
        C[i] += val;
    }
}
inline int sum(int x){
    int ret = 0;
    for(int i=x;i>0;i-=lowbit(i)){
        ret+=C[i];
    }
    return ret;
}

int cnt = 0;

void dfs(int u, int fa){
    leftid[u] = cnt + 1;
    for(int i = head[u]; ~i ; i = edge[i].next){
        int v = edge[i].to;
        if(v != fa){
            dfs(v, u);
        }
    }
    rightid[u] = ++cnt;
}

int main(){
    while(~scanf("%d", &n) && n){
        MS(C, 0);
        init();
        for(int i = 1; i <= n; i++){
            add(i, 1);
            sta[i]  =1;
        }
        int u, v;
        for(int i = 0; i < n -1; i++){
            scanf("%d %d", &u, &v);
            addedge(u, v);
            addedge(v, u);
        }
        cnt = 0;
        dfs(1, -1);
        cin>>m;
        char ope;

        while(m--){
            scanf(" %c %d", &ope, &u);
            int l  = leftid[u],  r = rightid[u];
            if(ope == 'C'){
                if(sta[r]){
                    sta[r] = 0;
                    add(r, -1);
                }else{
                    sta[r] = 1;
                    add(r, 1);
                }
            }else{
                int tp = sum(r) - sum(l - 1);
                printf("%d ", tp);
            }
        }

    }
    return 0;
}
原文地址:https://www.cnblogs.com/IMGavin/p/5703585.html