[POJ3321 Apple Tree]

[题目来源]:POJ Monthly--2007.08.05, Huang, Jinsong

[关键字]:树状数组

[题目大意]:一棵苹果树每个数字上长有1个苹果,有两种操作:1、改变一个树枝上的苹果数;2、询问以某个树枝为根的子树的苹果数量。

//====================================================================================================

[分析]:此题关键不在数据结构(区间和可以用树状数组或线段树), 主要是如何把树(不一定是二叉树)转化为数组来处理。首先建树(我采用的是邻接表), 然后DFS先根遍历该树, 对每个节点记录其最近序号(按照遍历顺序重新编号)和其子树的最小最大序号(也就是标记一棵树遍历的第一个和最后一个节点的遍历序号st, ed).剩下的就可以是典型的树状数组处理了.如:统计一个节点为根的树中apple数目时, 直接计算到st-, ed的和然后相减即可.

[代码]:

View Code
  1 type
2 rec = record
3 y, n: longint;
4 end;
5 var
6 n, m, tot, ans, dat, now: longint;
7 e: array[0..100100] of rec;
8 link: array[0..100100] of longint;
9 c: array[0..100100] of 0..1;
10 st, ed: array[0..100100] of longint;
11 tree: array[0..100100] of longint;
12
13 procedure build(root: longint);
14 var
15 t, y: longint;
16 begin
17 t := link[root];
18 st[root] := now;
19 ed[root] := now;
20 dec(now);
21 while t > 0 do
22 begin
23 y := e[t].y;
24 build(y);
25 if ed[y] < ed[root] then ed[root] := ed[y];
26 t := e[t].n;
27 end;
28 end;
29
30 procedure make(x, y: longint);
31 begin
32 inc(tot);
33 e[tot].y := y;
34 e[tot].n := link[x];
35 link[x] := tot;
36 end;
37
38 procedure ins(k, dat: longint);
39 begin
40 while k <= n do
41 begin
42 tree[k] := tree[k]+dat;
43 k := k+k and -k;
44 end;
45 end;
46
47 function find(k: longint):longint;
48 var
49 sum: longint;
50 begin
51 sum := 0;
52 while k >= 1 do
53 begin
54 sum := sum+tree[k];
55 k := k-k and -k;
56 end;
57 exit(sum);
58 end;
59
60 procedure init;
61 var
62 i, x, y: longint;
63 begin
64 readln(n);
65 fillchar(c,sizeof(c),0);
66 tot := 0;
67 for i := 1 to n-1 do
68 begin
69 readln(x,y);
70 make(x,y);
71 end;
72 now := n;
73 build(1);
74 for i := 1 to n do
75 begin
76 if c[i] = 1 then dat := -1 else dat := 1;
77 c[i] := c[i]+dat;
78 ins(st[i],dat);
79 end;
80 //for i := 1 to n do writeln(st[i],' ',ed[i]);
81 end;
82
83 procedure work;
84 var
85 i, x: longint;
86 ch: char;
87 begin
88 readln(m);
89 for i := 1 to m do
90 begin
91 read(ch);
92 case ch of
93 'C': begin
94 readln(x);
95 if c[x] = 1 then dat := -1 else dat := 1;
96 c[x] := c[x]+dat;
97 ins(st[x],dat);
98 end;
99 'Q': begin
100 readln(x);
101 ans := find(st[x]);
102 ans := ans-find(ed[x]-1);
103 writeln(ans);
104 end;
105 end;
106 end;
107 readln;
108 end;
109
110 begin
111 init;
112 work;
113 end.




你可能感兴趣的:(apple)