poj 3321 Apple Tree(树状数组)

辉煌北大的月赛题质量真高啊,这种树状数组真难想到。

树状数组的基本用法是区间,单点的应用,起初这个怎么都想不到如何套用到树状数组。

转化方法是 将树上的节点信息查询,转为深度优先中节点顺序(代表结点编号)。进结点与出结点分别代表该结点管辖范围。

题目大意级是说,给你一颗树,最初每个节点上都有一个苹果,有两种操作:修改(即修改某一个节点,修改时这一个节点苹果从有到无,或从无到有)和查询(查询某一个节点他的子树上有多少个苹果)。

由于此题数据比较大(N<=10^5),而且不是标准的二叉树,所以这里我们队每一个节点重新编号,另外为每一个节点赋一个左值和一个右值,表示这个节点的管辖范围。

也就是DFS搜索的时候做标记的过程,这样新的编号为1~6的节点所管辖的范围分别就是[1,6]  [2,4]   [3,3]  [4,4]  [5,6]  [6,6],其中左边的是左值,右边的是右值,节点1的区间是[1,6],正好这棵子树有6个节点,其他也一样

#include<cstdio>
#include<string>
#include<string.h>
#include<iostream>
#include<algorithm>
#include<map>
#include<iterator>
using namespace std;
#define N 100010
int n,m;

int lowbit(int x){return -x&x;}
void update(int *arr,int r,int num)
{
	int i;
	for(i=r;i<=n;i+=lowbit(i))
		arr[i]+=num;

}
int getsum(int *arr,int r)
{
	int i;
	int ans=0;
	for(i=r;i>0;i-=lowbit(i))
		ans+=arr[i];
	return ans;
}

int head[N];
int next[N];
int netb[N];
int deh1[N];
int deh2[N];
int cnt,depth;
int arr[N];
int a[N];
void init()
{
	int i;
	//memset(a,0,sizeof(a));
	memset(deh1,0,sizeof(deh1));
	memset(head,-1,sizeof(head));
	cnt=0;depth=0;
	for(i=1;i<=n;i++)
		update(arr,i,1),a[i]=1;

}
void add(int u,int v)
{
	netb[cnt]=v;next[cnt]=head[u];head[u]=cnt++;
}
void dfs(int u)
{
	deh1[u]=++depth;//代表左
	int i;
	for(i=head[u];~i;i=next[i])
	{
		int v=netb[i];
			dfs(v);
	}
	deh2[u]=depth;//代表右
}
int main()
{
	int i,j,k,u,v,m;
	char str[10];
	while(~scanf("%d",&n))
	{
		init();
		for(i=1;i<n;i++)
		{
			scanf("%d%d",&u,&v);
			add(u,v);//add(v,u);
		}
		dfs(1);
		scanf("%d",&m);
		for(i=1;i<=m;i++)
		{
			scanf("%s%d",str,&k);
			if(str[0]=='C') a[k]*=-1,update(arr,deh1[k],a[k]);//这里用deh1[k]左边也代表它的标号
			else
			{
				u=deh1[k]-1;
				v=deh2[k];
				k=getsum(arr,v)-getsum(arr,u);
				printf("%d\n",k);
			}
		}
	}
	return 0;
}
时间: 2024-10-11 05:15:07

poj 3321 Apple Tree(树状数组)的相关文章

POJ 3321 Apple Tree (树状数组)

Apple Tree Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 21191   Accepted: 6436 Description There is an apple tree outside of kaka's house. Every autumn, a lot of apples will grow in the tree. Kaka likes apple very much, so he has been

E - Apple Tree(树状数组+DFS序)

There is an apple tree outside of kaka's house. Every autumn, a lot of apples will grow in the tree. Kaka likes apple very much, so he has been carefully nurturing the big apple tree. The tree has N forks which are connected by branches. Kaka numbers

POJ3321 Apple Tree(树状数组)

先做一次dfs求得每个节点为根的子树在树状数组中编号的起始值和结束值,再树状数组做区间查询 与单点更新. #include<cstdio>#include<iostream>#include<cstdlib>#include<cstring>#include<string>#include<algorithm>#include<map>#include<queue>#include<vector>#

poj 3321:Apple Tree(树状数组,提高题)

Apple Tree Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 18623   Accepted: 5629 Description There is an apple tree outside of kaka's house. Every autumn, a lot of apples will grow in the tree. Kaka likes apple very much, so he has been

【树状数组】POJ 3321 Apple Tree

/** * @author johnsondu * @time 2015.8.25 20:04 * @problem POJ 3321 Apple Tree * @type Binary Index Tree * @description 从根节点开始,dfs遍历树,先访问的节点 * 记为beg, 从当前结点遍历访问到的最后的 * 一个节点,记为end.然后按照树状数组的 * 方法进行求解. * @url http://poj.org/problem?id=3321 */ #include <i

POJ 3321 Apple Tree (dfs+线段树)

题目大意: 修改树上的节点,然后求子树的和. 思路分析: dfs 重新编号,烂大街了... #include <cstdio> #include <iostream> #include <cstring> #include <algorithm> #define maxn 100005 #define lson num<<1,s,mid #define rson num<<1|1,mid+1,e using namespace std

POJ - 3321 Apple Tree (线段树 + 建树 + 思维转换)

POJ - 3321 Apple Tree Time Limit: 2000MS   Memory Limit: 65536KB   64bit IO Format: %I64d & %I64u Submit Status Description There is an apple tree outside of kaka's house. Every autumn, a lot of apples will grow in the tree. Kaka likes apple very muc

HDU 3333 Turing Tree 树状数组 离线查询

题意: 给你一个数列,然后有n个查询,问你给定区间中不同数字的和是多少. 思路还是比较难想的,起码对于蒟蒻我来说. 将区间按照先右端点,后左端点从小到大排序之后,对于每个查询,我只要维护每个数字出现的最后一次就可以了(这个结论稍微想一下就可以证明是正确的). 然后就是简单的点更新,区间求和问题了- #include <cstdio> #include <cstring> #include <iostream> #include <map> #include

hdu 1541/poj 2352:Stars(树状数组,经典题)

Stars Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 4052    Accepted Submission(s): 1592 Problem Description Astronomers often examine star maps where stars are represented by points on a plan

POJ 2892 Tunnel Warfare (树状数组+二分)

题目大意: 三个操作 D pos  将pos位置摧毁,让它和周围不相连. Q pos 问和pos 相连的有多少个村庄. R 修复最近摧毁的村庄. 思路分析: 树状数组记录这个区间有多少个1. 如果  [s-e] 有e-s+1个1 的话.那么这个区间是相连的. 这样的话,我们就可以用二分的办法求出与某个位置最大相连的数量. 还有这里二分 while(l<=r) { if(满足) { ans=mid; l=mid+1; } else r=mid-1; } #include <cstdio>