[poj3321]Apple Tree(dfs序+树状数组)

Apple Tree

Time Limit: 2000MS   Memory Limit: 65536K
Total Submissions: 26762   Accepted: 7947

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 carefully nurturing the big apple tree.

The tree has N forks which are connected by branches. Kaka numbers the forks by 1 to N and the root is always numbered by 1. Apples will grow on the forks and two apple won‘t grow on the same fork. kaka wants to know how many apples are there in a sub-tree, for his study of the produce ability of the apple tree.

The trouble is that a new apple may grow on an empty fork some time and kaka may pick an apple from the tree for his dessert. Can you help kaka?

Input

The first line contains an integer N (N ≤ 100,000) , which is the number of the forks in the tree.
The following N - 1 lines each contain two integers u and v, which means fork u and fork v are connected by a branch.
The next line contains an integer M (M ≤ 100,000).
The following M lines each contain a message which is either
"x" which means the existence of the apple on fork x has been changed. i.e. if there is an apple on the fork, then Kaka pick it; otherwise a new apple has grown on the empty fork.
or
"x" which means an inquiry for the number of apples in the sub-tree above the fork x, including the apple (if exists) on the fork x
Note the tree is full of apples at the beginning

Output

For every inquiry, output the correspond answer per line.

Sample Input

3
1 2
1 3
3
Q 1
C 2
Q 1

Sample Output

3
2

Source

POJ Monthly--2007.08.05, Huang, Jinsong

继续继续继续

dfs序嘛

原来之前理解的是错的

其实就是tarjan的dfn与low数组

得出dfn与low后

dfn[i]是起点,low[i]是终点,中间的一段就是点i的子树了

这样dfs序就可以“方便的维护子树”

而对于大部分按照dfs序维护序列的题,与树状数组是相当好的组合

这道题差不多是裸题了,多开一个表示当前节点状态的数组就可以了

 1 #include<stdio.h>
 2 #include<stdlib.h>
 3 #include<string.h>
 4 int ap[100010],bit[100010];
 5 int bg[100010],ed[100010],cnt=0;
 6 int n;
 7 typedef struct{
 8     int to,nxt;
 9 }edge;
10 edge gra[200010];
11 int head[100010],num=0;
12 int add(int frm,int to){
13     gra[++num].nxt=head[frm];
14     gra[num].to=to;
15     head[frm]=num;
16     return 0;
17 }
18 int dfs(int u,int fa){
19     bg[u]=++cnt;
20     int j;
21     for(j=head[u];j;j=gra[j].nxt){
22         if(gra[j].to!=fa)dfs(gra[j].to,u);
23     }
24     ed[u]=cnt;
25     return 0;
26 }
27 int lb(int x){
28     return x&(-x);
29 }
30 int c(int x){
31     int num=ap[x];
32     x=bg[x];
33     while(x<=n){
34         bit[x]+=num;
35         x+=lb(x);
36     }
37     return 0;
38 }
39 int q(int x){
40     int a1=0,a2=0;
41     int e=ed[x];
42     while(e){
43         a1+=bit[e];
44         e-=lb(e);
45     }
46     int b=bg[x]-1;
47     while(b){
48         a2+=bit[b];
49         b-=lb(b);
50     }
51     return a1-a2;
52 }
53 int main(){
54     scanf("%d",&n);
55     for(int i=1;i<n;i++){
56         int x,y;
57         scanf("%d %d",&x,&y);
58         add(x,y);
59         add(y,x);
60     }
61     dfs(1,0);
62     for(int i=1;i<=n;i++){
63         ap[i]=1;
64         c(i);
65     }
66     int m;
67     scanf("%d",&m);
68     for(int i=1;i<=m;i++){
69         char in[2];
70         int x;
71         scanf("%s %d",in,&x);
72         if(in[0]==‘C‘){
73             ap[x]*=-1;
74             c(x);
75         }
76         else printf("%d\n",q(x));
77     }
78     return 0;
79 }

睡觉

时间: 2024-11-09 16:22:40

[poj3321]Apple Tree(dfs序+树状数组)的相关文章

POJ 3321 Apple Tree DFS序 + 树状数组

多次修改一棵树节点的值,或者询问当前这个节点的子树所有节点权值总和. 首先预处理出DFS序L[i]和R[i] 把问题转化为区间查询总和问题.单点修改,区间查询,树状数组即可. 注意修改的时候也要按照dfs序修改,因为你查询就是按照dfs查的,所以修改也要用dfs序修改 L[i]是唯一的. #include <cstdio> #include <cstdlib> #include <cstring> #include <cmath> #include <

Codeforces Round #225 (Div. 1) C. Propagating tree dfs序+树状数组

C. Propagating tree Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/contest/383/problem/C Description Iahub likes trees very much. Recently he discovered an interesting tree named propagating tree. The tree consists of n nodes numb

1076E/Educational Codeforces Round 54-E. Vasya and a Tree&lt;&lt;dfs序 树状数组

题意 给定一棵树,初始每个节点权值为零,q次更改,每次修改将以v为顶点的深度为d的子树全部加上x,最后输出所有节点的权重. 思路 题目只要求每个点最后的值,那么经过观察,发现一个点最后的权值大小只与他的父节点的更新有关,那么我们就只需要考虑他的父节点到他这条链上的情况,把这条链拿出来成为线段,然后维护后缀和就能得到此点上的权值.每个节点的贡献为给$[h,h+d]$增加$x$,所以维护时,只要在$h+d$点上加上$x$即可. 但是问题考察的是一棵树,我们就需要动态来完成这条链,我们采用dfs序去扫

HDU 5293 Tree chain problem 树形dp+dfs序+树状数组+LCA

题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=5293 题意: 给你一些链,每条链都有自己的价值,求不相交不重合的链能够组成的最大价值. 题解: 树形dp, 对于每条链u,v,w,我们只在lca(u,v)的顶点上处理它 让dp[i]表示以i为根的指数的最大值,sum[i]表示dp[vi]的和(vi为i的儿子们) 则i点有两种决策,一种是不选以i为lca的链,则dp[i]=sum[i]. 另一种是选一条以i为lca的链,那么有转移方程:dp[i]=

【bzoj1146】[CTSC2008]网络管理Network 倍增LCA+dfs序+树状数组+主席树

题目描述 M公司是一个非常庞大的跨国公司,在许多国家都设有它的下属分支机构或部门.为了让分布在世界各地的N个部门之间协同工作,公司搭建了一个连接整个公司的通信网络.该网络的结构由N个路由器和N-1条高速光缆组成.每个部门都有一个专属的路由器,部门局域网内的所有机器都联向这个路由器,然后再通过这个通信子网与其他部门进行通信联络.该网络结构保证网络中的任意两个路由器之间都存在一条直接或间接路径以进行通信. 高速光缆的数据传输速度非常快,以至于利用光缆传输的延迟时间可以忽略.但是由于路由器老化,在这些

BZOJ 2434: [Noi2011]阿狸的打字机( AC自动机 + DFS序 + 树状数组 )

一个串a在b中出现, 那么a是b的某些前缀的后缀, 所以搞出AC自动机, 按fail反向建树, 然后查询(x, y)就是y的子树中有多少是x的前缀. 离线, 对AC自动机DFS一遍, 用dfs序+树状数组维护, DFS到的查询点就回答询问.时间复杂度O(|ACAM|+QlogQ) ------------------------------------------------------------------------------------------- #include<cstdio>

【BZOJ】1146: [CTSC2008]网络管理Network(树链剖分+线段树套平衡树+二分 / dfs序+树状数组+主席树)

第一种做法(时间太感人): 这题我真的逗了,调了一下午,疯狂造数据,始终找不到错. 后来发现自己sb了,更新那里没有打id,直接套上u了.我.... 调了一下午啊!一下午的时光啊!本来说好中午A掉去学习第二种做法,噗 好吧,现在第一种做法是hld+seg+bst+二分,常数巨大,log^4级别,目前只会这种. 树剖后仍然用线段树维护dfs序区间,然后在每个区间建一颗平衡树,我用treap,(这题找最大啊,,,囧,并且要注意,这里的rank是比他大的数量,so,我们在二分时判断要判断一个范围,即要

[POI2007][BZOJ1103] 大都市meg|dfs序|树状数组

1103: [POI2007]大都市meg Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 1350  Solved: 697[Submit][Status][Discuss] Description 在经济全球化浪潮的影响下,习惯于漫步在清晨的乡间小路的邮递员Blue Mary也开始骑着摩托车传递邮件了.不过,她经常回忆起以前在乡间漫步的情景.昔日,乡下有依次编号为1..n的n个小村庄,某些村庄之间有一些双向的土路.从每个村庄都恰好有一条路径到达

【bzoj3779】重组病毒 LCT+树上倍增+DFS序+树状数组区间修改区间查询

题目描述 给出一棵n个节点的树,每一个节点开始有一个互不相同的颜色,初始根节点为1. 定义一次感染为:将指定的一个节点到根的链上的所有节点染成一种新的颜色,代价为这条链上不同颜色的数目. 现有m次操作,每次为一下三种之一: RELEASE x:对x执行一次感染: RECENTER x:把根节点改为x,并对原来的根节点执行一次感染: REQUEST x:询问x子树中所有节点感染代价的平均值. 输入 输入的第一行包含两个整数n和m,分别代表局域网中计算机的数量,以及操作和询问的总数.接下来n-1行,