【POJ 3321】Apple Tree【树状数组&DFS】

苹果树

时限: 2000MS 内存限制: 65536K

描述

卡卡家门外有一棵苹果树。每年秋天,树上都会种很多苹果。卡卡非常喜欢苹果,因此他一直在精心培育大苹果树。

该树有N个分支,这些分支由分支连接。Kaka用1到N对叉进行编号,并且根始终用1编号。在叉上将生长苹果,而在同一叉上将不会生长两个苹果。卡卡想了解子树中有多少苹果,以便研究苹果树的生产能力。

问题在于,有时空叉上会长出一个新苹果,卡卡可能会从树上摘下一个苹果作为甜点。你能帮卡卡吗?

在这里插入图片描述

输入项

第一行包含一个整数Ñ(Ñ ≤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

分析:

对这颗进行 d f s dfs dfs遍历 并记录每一个点的 d f s dfs dfs序号 ( s t [ i ] ) (st[i]) (st[i])
在一个节点的所有儿子都被遍历过后 记录当前 e n [ i ] en[i] en[i]为当前最大 d f s dfs dfs序号的节点的 d f s dfs dfs序号
C x C x Cx表示修改 x x x点的权值 Q x Q x Qx表示求区间 s t [ x ] st[x] st[x] e n [ x ] en[x] en[x]的和
利用树状数组可以轻松实现……

CODE:

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#define N 100005
using namespace std;
typedef long long ll;
ll n,m,tot,head[N],st[N],en[N],c[N],e[N],qwq;  //注意开long long
struct node{
    
    
	ll to,next;
}a[2*N];
void add(ll x,ll y)
{
    
    
	a[++tot].to=y;
	a[tot].next=head[x];  //邻接表 poj识别不了那种简便写法
	head[x]=tot;
}
ll lowbit(ll x)
{
    
    
	return x&(-x);
}
void update(ll x,ll y)
{
    
    
	for(;x<=n;x+=lowbit(x))  //修改权值函数
	c[x]+=y;
}
ll find(ll x)
{
    
    
	ll ans=0;
	for(;x;x-=lowbit(x))  //求和函数
		ans+=c[x];
	return ans;
}
void dfs(ll dep)
{
    
    
	tot++;
	st[dep]=tot;
	for(int i=head[dep];i;i=a[i].next)  //遍历树
		dfs(a[i].to);
	en[dep]=tot;
}
int main(){
    
    
	scanf("%lld",&n);
	for(ll i=1;i<n;i++)
	{
    
    
		ll u,v;
		scanf("%lld%lld",&u,&v);
		add(u,v);  //建立
	}
	tot=0;   //注意清空 刚刚建立了邻接表
	dfs(1);
	for(ll i=1;i<=n;i++)
	{
    
    
		e[i]=1;
		update(st[i],1);  //先改权为1
	}
	scanf("%lld",&m);
	for(ll i=1;i<=m;i++)
	{
    
    
		char X;
		cin>>X;
		if(X=='Q')
		{
    
    
			scanf("%lld",&qwq);
			printf("%lld\n",find(en[qwq])-find(st[qwq]-1));  //区间和
		}else{
    
    
			scanf("%lld",&qwq);
			if(!e[qwq])
			{
    
    
				update(st[qwq],1);  //判断还有哪些未改权
				e[qwq]=1;
			}else{
    
    
				update(st[qwq],-1);
				e[qwq]=0;
			}
		}
	}
	return 0;
}

猜你喜欢

转载自blog.csdn.net/dgssl_xhy/article/details/108071325