POJ 3321 Apple Tree dfs+二叉索引树

题目: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\n", 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 }
View Code

 

posted @ 2013-09-13 20:01  Anti-Magic  阅读(147)  评论(0编辑  收藏  举报