这题难的不是树状数组(其实树状数组很简单),主要是映射到树状数组。对树和图还不熟啊,导致这题就是借了别人的思路,可以用邻接表建树,
然后dfs一次就可以算出对某个节点它的第一个下标(在树状数组中)和最后一个下标。那个更改的时候就用这两个下标就行了。
比如下面的样例
1 2
2 5
1 3
2 4
那么dfs一次之后,就会得到如下坐标(1,5)(3,5)(2,2)(5,5)(4,4)(建图不一样的话,后面对应出来的坐标会不一样,每一对表示样例中的数的第一个
下标和最后一个下标),也就是说从1开始,那么第一个就是1,最后一个是5(这个5不是节点5,而是节点4,但是第5个被访问,其实第几个访问没关系的,
我们只是要一个区间而已,这个区间代表包含了这棵树(或者子树)),那么和它有关的就是[1,5],对于2这个点它在树中是第3个访问的(第2个是节点3)
那么2的第一个下标就是3,在这个子树中最后一个访问的还是5,所以和它有关的区间就是[3,5].同理可以得到其他几个点所对应的坐标,不过中间可能不
怎么好想,我是这么理解的,对每一个点找出影响它的所有点然后放在一个区间中,那么改变时就好办了,而放在一个区间中,就可以用dfs了。
代码如下(如果对图理解的好的话,建议自己先写)

CODE
1
/**//*
2
ID:Klion
3
PROG:POJ_3321
4
LANG:C++
5
关键是映射到树状数组中
6
*/
7
#include <stdio.h>
8
#include <stdlib.h>
9
#include <string.h>
10
typedef struct node
11

{
12
int data;
13
struct node * next;
14
}Node;//邻接表
15
typedef struct
16

{
17
int data;//似乎这个域没用
18
Node * first;
19
}Adj;
20
Adj fork[100006];//邻接表
21
int tree[100006];//树状数组
22
int low[100006],hight[100006];//对应每一个点的开始区间点和结束区间点
23
//bool mark[100006];
24
int cnt;//dfs用的,用来确定区间的起点和终点
25
void dfs(int v)
26

{//dfs 确定区间的起点和终点
27
Node * p = fork[v].first;
28
mark[v] = true;
29
++cnt;
30
low[v] = cnt;//开始点
31
while(NULL != p)
32
{
33
//if(!mark[p->data])
34
dfs(p->data);
35
p = p->next;
36
}
37
hight[v] = cnt;//结束点也就是访问完了这棵树(或者子树)之后cnt的值
38
//其中没访问一个点cnt加1
39
}
40
void update(int x,int val)
41

{//树状数组的更新
42
while(x <= 100006)
43
{
44
tree[x] += val;
45
x += (x & -x);
46
}
47
}
48
int read(int x)
49

{//树状数组的求和
50
int ret = 0;
51
while(x > 0)
52
{
53
ret += tree[x];
54
x -= (x & -x);
55
}
56
return ret;
57
}
58
void init()
59

{//初始化邻接表的其实节点
60
for(int i = 0;i < 100006;i++)
61
{
62
fork[i].data = i;
63
fork[i].first = NULL;
64
}
65
return ;
66
}
67
void init_tree()
68

{//初始化树状数组
69
for(int i = 1;i < 100006;i++)
70
{//对每个点都赋值为1
71
update(i,1);
72
}
73
return ;
74
}
75
void get_low_hight()
76

{//得到每个点的区间开始点和区间结束点
77
cnt = 0;
78
//memset(mark,false,sizeof(mark));
79
dfs(1);//从根节点开始
80
}
81
int main(void)
82

{
83
freopen("3321.in","r",stdin);
84
freopen("3321.out","w",stdout);
85
int n,m;
86
int a,b;
87
int ans;
88
int x;
89
char cq[2];
90
Node * tmp;
91
init();
92
scanf("%d",&n);
93
for(int i = 1;i < n;i++)
94
{//输入数据,建树
95
tmp = new Node;
96
scanf("%d%d",&a,&b);
97
tmp->data = b;
98
tmp->next = fork[a].first;
99
fork[a].first = tmp;
100
/**//*这段可不要,也就是一个单向边,那么mark数组也可以不要了
101
tmp = new Node;
102
tmp->data = a;
103
tmp->next = fork[b].first;
104
fork[b].first = tmp;*/
105
}
106
get_low_hight();//得到每个点的区间开始和结束
107
init_tree();//初始化树状数组
108
scanf("%d%*c",&m);
109
while(m--)
110
{//m个操作
111
scanf("%s%d",&cq,&x);
112
if('Q' == cq[0])
113
{//如果是询问的话
114
ans = read(hight[x])-read(low[x]-1);//后面是low[x]-1,也就是求low[x]-hight[x]的和
115
printf("%d\n",ans);
116
}
117
else
118
{
119
//更新
120
ans = read(low[x]) - read(low[x]-1);
121
//其实可以开一个数组,这里用了先读值然后再该,会增加一些时间
122
if(0 == ans)
123
ans = 1;//长出一个苹果
124
else
125
ans = -1;//摘掉这个苹果
126
update(low[x],ans);//更新树状数组
127
}
128
}
129
return 0;
130
}
131