poj 3321
先将树DFS一次得到一个序列,按这个顺序把节点上的苹果数放到一个一维数组,每棵子树的苹果数就相当于数组对应的一段元素的和。这个数组我们用树状数组来维护就可以加快速度。
1 #include <cstdio> 2 #include <algorithm> 3 #pragma warning(disable:4996) 4 using namespace std; 5 int bit[100001], a[100001];//bit -- binary indexed tree 6 int lowBit(int x){ 7 return x & (-x); 8 } 9 void add(int idx, int size, int val){ 10 while (idx <= size){ 11 bit[idx] += val; 12 idx += lowBit(idx); 13 } 14 } 15 int sum(int idx){ 16 int ret = 0; 17 while (idx > 0){ 18 ret += bit[idx]; 19 idx -= lowBit(idx); 20 } 21 return ret; 22 } 23 struct Edge{ 24 int v, next; 25 }edge[200001]; 26 int edgeNum, head[100001]; 27 void addEdge(int u, int v){ 28 edge[edgeNum].v = v; 29 edge[edgeNum].next = head[u]; 30 head[u] = edgeNum++; 31 } 32 int posMap[100001][2], counter; 33 void dfs(int u){ 34 posMap[u][0] = ++counter; 35 for (int i = head[u]; i != -1; i = edge[i].next){ 36 if (posMap[edge[i].v][0] == -1){ 37 dfs(edge[i].v); 38 } 39 } 40 posMap[u][1] = counter; 41 } 42 int main(){ 43 int n, m; 44 while (~scanf("%d", &n)){ 45 int u, v; 46 edgeNum = 0; 47 fill(head + 1, head + 1 + n, -1); 48 for (int i = 1; i <= n; i++){ 49 bit[i] = lowBit(i); 50 a[i] = 1; 51 } 52 for (int i = 1; i < n; i++){ 53 scanf("%d%d", &u, &v); 54 addEdge(u, v); 55 addEdge(v, u); 56 } 57 for (int i = 1; i <= n; i++){ 58 posMap[i][0] = -1; 59 } 60 counter = 0; 61 dfs(1); 62 scanf("%d", &m); 63 char op; 64 int k; 65 for (int i = 0; i < m; i++){ 66 scanf("%*c%c%d", &op, &k); 67 if (op == 'Q'){ 68 printf("%d\n", sum(posMap[k][1]) - sum(posMap[k][0] - 1)); 69 } 70 else{ 71 if (a[posMap[k][0]]){ 72 add(posMap[k][0], n, -1); 73 } 74 else{ 75 add(posMap[k][0], n, 1); 76 } 77 a[posMap[k][0]] = 1 - a[posMap[k][0]]; 78 } 79 } 80 } 81 return 0; 82 }