Apple Tree树状数组、前向星、DFS序(C语言)
题目
输入值
第一行包含一个整数Ñ(Ñ ≤100,000),这是树中的叉的数量。
接下来的N -1行分别包含两个整数u和v,这意味着fork u和fork v通过分支连接。
下一行包含的整数中号(中号≤100,000)。
以下中号行,每行包含一个消息,该消息或者是
“ Ç X ”,这意味着苹果上叉存在X已经变了。例如,如果叉子上有一个苹果,则卡卡(Kaka)摘下;否则,空叉上会长出一个新苹果。
或
“ Q x ”,表示查询叉子x上方子树中的苹果数量,包括叉子x上的苹果(如果存在),
请注意,树的开头充满了苹果
输出量
对于每个查询,每行输出相应的答案。
样本输入
3
1 2
1 3
3
Q 1
C 2
Q 1
样本输出
3
2
代码
#include <stdio.h>
typedef struct edge{
int to;
int next;
}Edge;
int n,c[100001],head[100001],in[100001],out[100001],ifexist[100001],count = 0;
Edge edge[100001];
int lowbit(int index){
return index&(-index);
}
void addEdge(int father, int son){
edge[++count].to = son;
edge[count].next = head[father];
head[father] = count;
}
int sum(int index){
int res = 0;
while(index>0){
res += c[index];
index -= lowbit(index);
}
return res;
}
void dfs(int index){
in[index] = ++count;
for(int i = head[index];i;i=edge[i].next){
dfs(edge[i].to);
}
out[index] = count;
}
void update(int index, int add){
while(index <= n){
c[index] += add;
index += lowbit(index);
}
}
int main(){
int m,pre,son,result[10000],cnt = 0,i;
char ch;
scanf("%d",&n);
for(i = 1; i<=n-1; i++){
scanf("%d %d",&pre,&son);
addEdge(pre,son);
}
count = 0;
dfs(1);
for(i = 1; i<=n; i++){
update(in[i],1);
ifexist[i] = 1;
}
scanf("%d",&m);
for(i = 1; i<=m; i++){
getchar();
scanf("%c %d",&ch,&pre);
if(ch == 'C'){
if(ifexist[pre]){
update(in[pre],-1);
}
else{
update(in[pre],1);
}
ifexist[pre] = 1-ifexist[pre];
}
else if(ch == 'Q'){
result[cnt++] = sum(out[pre]) - sum(in[pre] - 1);
}
}
for(i = 0; i<cnt; i++){
printf("%d\n",result[i]);
}
return 0;
}