Apple Tree树状数组、前向星、DFS序(C语言)

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;
} 

猜你喜欢

转载自blog.csdn.net/tblwbr520/article/details/110210759