POJ 3321-Apple Tree-树状数组+dfs序

计算一个树的子树节点权值和,节点权值可以单个修改。

利用dfs序把一颗树投影到数组里,维护dfs序和子节点个数,然后用树状数组即可。

  1 #include <cstdio>
  2 #include <algorithm>
  3 #include <cstring>
  4
  5 using namespace std;
  6
  7 const int maxn = 1e5+10;
  8 int N,M,c[maxn],chdnum[maxn];
  9 int id_dfs[maxn],cnt_dfs;
 10 bool vis[maxn];
 11
 12 struct Edge{
 13     int to,next;
 14
 15 }edge[4*maxn];
 16 int head[maxn],tol;
 17
 18 int add_edge(int u,int v)
 19 {
 20     edge[tol].to = u;
 21     edge[tol].next = head[v];
 22     head[v] = tol++;
 23
 24     edge[tol].to = v;
 25     edge[tol].next = head[u];
 26     head[u] = tol++;
 27 }
 28
 29 int dfs(int u)
 30 {
 31     int chd = 1;
 32     vis[u] = true;
 33     if(id_dfs[u] == -1) id_dfs[u] = cnt_dfs++;
 34
 35     for(int i = head[u];~i;i = edge[i].next) if(!vis[edge[i].to])
 36     {
 37         int v = edge[i].to;
 38         chd += dfs(v);
 39     }
 40     return chdnum[u] = chd;
 41 }
 42
 43 int lowbit(int x)
 44 {
 45     return x & (-x);
 46 }
 47
 48 void update(int x,int a)
 49 {
 50     while( x <= N)
 51     {
 52         c[x] += a;
 53         x += lowbit(x);
 54     }
 55 }
 56
 57 int getsum(int x)
 58 {
 59     int res = 0;
 60     while(x > 0)
 61     {
 62         res += c[x];
 63         x -= lowbit(x);
 64     }
 65     return res;
 66 }
 67
 68 int query(int l,int r)
 69 {
 70     return getsum(r) - getsum(l-1);
 71 }
 72
 73 int main()
 74 {
 75     while(~scanf("%d",&N))
 76     {
 77         memset(head,-1,sizeof head);
 78         memset(c,0,sizeof c);
 79         memset(id_dfs,-1,sizeof id_dfs);
 80         memset(vis,false,sizeof vis);
 81         cnt_dfs = 1;
 82         tol = 0;
 83
 84         for(int i=0,u,v;i<N-1;i++)
 85         {
 86             scanf("%d%d",&u,&v);
 87             add_edge(u,v);
 88         }
 89
 90         dfs(1);
 91
 92         for(int i=1;i<=N;i++)
 93         {
 94             //printf("i: dfs:%d\n",i,id_dfs[i]);
 95             update(id_dfs[i],1);
 96         }
 97         scanf("%d",&M);
 98
 99         char op[5];
100         int x;
101         for(int i=0;i<M;i++)
102         {
103             scanf("%s%d",op,&x);
104             //printf("sum:%d chnum:%d id:%d\n",query(id_dfs[x],id_dfs[x]),chdnum[x],id_dfs[x]);
105             if(op[0] == ‘Q‘)
106             {
107                 printf("%d\n",getsum(id_dfs[x]+chdnum[x]-1) - getsum(id_dfs[x]-1) );
108             }
109             else
110             {
111                 if(query(id_dfs[x],id_dfs[x])) update(id_dfs[x],-1);
112                 else         update(id_dfs[x],1);
113             }
114         }
115     }
116 }
时间: 2024-08-10 17:09:05

POJ 3321-Apple Tree-树状数组+dfs序的相关文章

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

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

[题意]阿狸喜欢收藏各种稀奇古怪的东西,最近他淘到一台老式的打字机.打字机上只有28个按键,分别印有26个小写英文字母和'B'.'P'两个字母. 经阿狸研究发现,这个打字机是这样工作的: l 输入小写字母,打字机的一个凹槽中会加入这个字母(这个字母加在凹槽的最后). l 按一下印有'B'的按键,打字机凹槽中最后一个字母会消失. l 按一下印有'P'的按键,打字机会在纸上打印出凹槽中现有的所有字母并换行,但凹槽中的字母不会消失. 我们把纸上打印出来的字符串从1开始顺序编号,一直到n.打字机有一个非

UCF Local Programming Contest 2018 E题(树状数组+dfs序)

如果这道题没有一个限制,那么就是一道树状数组+dfs序的裸题 第一个请求或许会带来困惑,导致想要动态建树,如果真的动态修改树,那么dfs序必定会改变,很难维护,并且数据很大,暴力应该会T 所以不妨先把全部的节点建好,这样只需要求一次dfs序,而对于第一种操作 我们只需要再那个位置减去在他之前的dfs序的bouns求和,并在这个的后一个位置+回来,这样就有这个点被修改,并且成为了一个新点,等同于要求的操作 #include<iostream> #include<cstdio> #in

HDU5293(SummerTrainingDay13-B Tree DP + 树状数组 + dfs序)

Tree chain problem Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 1798    Accepted Submission(s): 585 Problem Description Coco has a tree, whose vertices are conveniently labeled by 1,2,-,n.The

POJ3321 Apple Tree(树状数组)

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

【BZOJ-1103】大都市meg 树状数组 + DFS序

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

BZOJ2434 NOI2011 阿狸的打字机 AC自动机+树状数组+DFS序

题意:给定三个操作:1.在当前字符串的末尾添加一个字符c  2.在当前字符串的末尾删除一个字符  3.记录当前字符串并对其标号.再给出N组询问,每组询问需回答第x个字符串在第y个字符串中出现的次数 题解: 首先按照如下规则建Trie,设当前节点为t,第i个字符串的结尾在Trie中的位置为mark[i]: 1.插入操作:看t是否有c这个儿子,有则t=t->child[c],否则t->child[c]=NewNode,t=t->child[c] 2.删除操作:t=t->father 3

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

2434: [Noi2011]阿狸的打字机 Time Limit: 10 Sec  Memory Limit: 256 MBSubmit: 2545  Solved: 1419[Submit][Status][Discuss] Description 阿狸喜欢收藏各种稀奇古怪的东西,最近他淘到一台老式的打字机.打字机上只有28个按键,分别印有26个小写英文字母和'B'.'P'两个字母.经阿狸研究发现,这个打字机是这样工作的:l 输入小写字母,打字机的一个凹槽中会加入这个字母(这个字母加在凹槽的最

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

Description 打字机上只有28个按键,分别印有26个小写英文字母和'B'.'P'两个字母.经阿狸研究发现,这个打字机是这样工作的: ·输入小写字母,打字机的一个凹槽中会加入这个字母(这个字母加在凹槽的最后). ·按一下印有'B'的按键,打字机凹槽中最后一个字母会消失. ·按一下印有'P'的按键,打字机会在纸上打印出凹槽中现有的所有字母并换行,但凹槽中的字母不会消失. 例如,阿狸输入aPaPBbP,纸上被打印的字符如下: a aa ab 我们把纸上打印出来的字符串从1开始顺序编号,一直到