题目:http://poj.org/problem?id=3321
动态更新某个元素,并且求和,显然是二叉索引树,但是节点的标号不连续,二叉索引树必须是连续的,所以需要转化成连续的,多叉树的形状已经建好,只要重新标号成连续的就行了。
感觉重新标号是这个题最难的地方,否则就是个纯水题了。。。
重新标号是看的别人的。。。用dfs遍历多叉树标号。
1 #include <stdio.h> 2 #include <stdlib.h> 3 #include <string.h> 4 5 int item = 0; 6 int c[100010], n; 7 int start[100010], end[100010]; 8 9 struct Tree 10 { 11 int num; 12 struct Tree *next; 13 Tree() 14 { 15 next = NULL; 16 num = 0; 17 } 18 }tree[100010]; 19 20 int lowbit(int x) 21 { 22 return x & (-x); 23 } 24 25 void add(int x, int y) 26 { 27 while(x <= n) 28 { 29 c[x] += y; 30 x += lowbit(x); 31 } 32 } 33 34 int sum(int x) 35 { 36 int ret = 0; 37 while(x) 38 { 39 ret += c[x]; 40 x -= lowbit(x); 41 } 42 return ret; 43 } 44 45 int query(int x, int y) 46 { 47 return sum(y) - sum(x-1); 48 } 49 50 void dfs(int x) 51 { 52 start[x] = ++item; 53 struct Tree *p = tree[x].next; 54 while(p != NULL) 55 { 56 if(start[p->num] == 0) 57 dfs(p->num); 58 p = p->next; 59 } 60 end[x] = item; 61 } 62 63 int main() 64 { 65 int u, v; 66 scanf("%d", &n); 67 memset(tree, 0, sizeof(tree)); 68 memset(start, 0, sizeof(start)); 69 memset(c, 0, sizeof(c)); 70 for(int i = 1; i < n; i++) 71 { 72 scanf("%d %d", &u, &v); 73 struct Tree *p = new Tree; 74 p->num = v; 75 p->next = tree[u].next; 76 tree[u].next = p; 77 } 78 dfs(1); 79 for(int i = 1; i <= n; i++) 80 { 81 add(i, 1); 82 } 83 int q, z; 84 char cmd[2]; 85 scanf("%d", &q); 86 while(q--) 87 { 88 scanf("%s %d", cmd, &z); 89 if(cmd[0] == 'Q') 90 { 91 printf("%d ", query(start[z], end[z])); 92 } 93 else 94 { 95 if(sum(start[z]) - sum(start[z]-1) == 1) 96 add(start[z], -1); 97 else add(start[z], 1); 98 } 99 } 100 return 0; 101 }