POJ 3321 Apple Tree 树状数组 树到数组的映射 区间求和
来源:互联网 发布:阿里云镜像是什么 编辑:程序博客网 时间:2024/05/16 10:15
我觉得是一道很不错的题目了,自己写出来的感觉真是不错。。。(虽然是看了别人的题解),总之写完之后我又回过头思考了一下,发现大概的思考路径可能是这样:
这道题目的重点就是在于对于操作Q的处理上,也就是求和。一个很朴素的想法就是遍历子树,可是当需要大量操作的时候,这样的是不行的。然后就想到利用树状数组进行区间求和,可是题目并没有说明这棵是一个二叉树,而且也不能保证每一棵子树的编号最终都落在同一个区间里面,那么我们这时候就需要对这棵树进行重新处理,也就是重新编号,使得它满足我们需要的这一个性质,也就是在求解一棵子树上的苹果的数量时候,它的子树的号码都能够落在一个连续区间里面,同时,保存下这棵子树的子树的编号范围,要求查询的时候可以直接用树状数组来求和。
这应该就是这道题目的一个大致的想法。至于还有别的题解说需要手动开栈,我自测了一下,在我的这种用数组模拟邻接表的建图方式下,是不需要手动开栈的。
Tips:通过DFS来给每一个子树保存它的子树的范围,vis数组用在DFS里面表示某一个节点是否被访问过
first,sz,init,addeage 以及edge数组都是用来模拟邻接表建图的。
lb,query,update用于树状数组的操作,Apple数组用来表示这棵树上是不是有苹果。
low数组和high数组用来表示一个子树的子树的范围,也就是保存其子树的最小编号和最大编号。
还是先把AC的代码拿出来吧,我会选择中间的DFS进行说明的,毕竟我感觉这个题目的关键就在于此
#include<cstdio>#include<cstring>#include<algorithm>using namespace std;struct Node{ int v,next; Node(int a=0,int b=0):v(a),next(b){};}edge[100005];inline int lb(int x){return x&-x;}int n,m,first[100005],dep,x,y,low[100005],high[100005],num[100005],sz,apple[100005],query(int x);bool vis[100005];char c;void addedge(),init(),update(int x,int val),dfs(int x);int main(){ while(scanf("%d",&n)!=EOF){ init(); for(int i=1;i<n;++i) scanf("%d%d",&x,&y),addedge(); dfs(1); scanf("%d%*c",&m); for(int i=0;i<m;++i){ scanf("%c%d%*c",&c,&x); if(c=='C') (apple[x]==1)?(update(low[x],-1),apple[x]=0):(update(low[x],1),apple[x]=1); else printf("%d\n",query(high[x])-query(low[x]-1)); } } return 0;}void update(int x,int val){ while(x<=n)num[x]+=val,x+=lb(x);}int query(int x){ int sum=0; while(x>0)sum+=num[x],x-=lb(x); return sum;}void init(){ sz=dep=0; memset(vis,0,sizeof(bool)*(n+1)); memset(first,-1,sizeof(int)*(n+1)); memset(num,0,sizeof(int)*(n+1)); for(int i=1;i<=n;++i){ apple[i]=1; update(i,1); //一开始每个分支都有一个苹果 }}void addedge(){ edge[sz]=Node(y,first[x]); first[x]=sz++;}void dfs(int x){ low[x]=++dep; vis[x]=true; for(int i=first[x];i!=-1;i=edge[i].next) if(!vis[edge[i].v]) dfs(edge[i].v); high[x]=dep;}
- POJ 3321 Apple Tree 树状数组 树到数组的映射 区间求和
- 【POJ 3321】 Apple Tree (dfs重标号设区间+树状数组求和)
- poj 3321 Apple Tree(dfs序+树状数组求和模型)
- poj 3321 Apple Tree(树状数组)(区间建树)
- poj 3321Apple Tree(树状数组+dfs映射)
- poj 3321 Apple Tree( 树状数组 )
- POJ 3321 apple tree 树状数组
- POJ 3321 Apple Tree(DFS+树状数组)
- POJ 3321 Apple Tree 树状数组
- poj 3321 apple tree 树状数组 水
- POJ 3321 Apple Tree(DFS+树状数组)
- POJ 3321 Apple Tree 树状数组
- POJ 3321 Apple Tree (树状数组)
- POJ 3321 Apple Tree (dfs + 树状数组)
- POJ 3321 Apple Tree (DFS + 树状数组)
- Poj 3321 Apple Tree - 树状数组
- [poj 3321]Apple Tree[树状数组]
- POJ 3321 Apple Tree DFS + 树状数组
- Universal-Image-Loader源码阅读(9)-utils/StorageUtils
- 【cocos2d-x从c++到js】JS与C++的交互1——JS代码调用C++代码
- 网站优化解读
- 崩盘论不止,房价上涨不止
- HDU 5835 Danganronpa(贪心)
- POJ 3321 Apple Tree 树状数组 树到数组的映射 区间求和
- consul三节点的集群搭建
- 【数据库】数据库增加列或删除列操作
- React Native 学习笔记(一)
- DiallogFragment的如何设置全屏
- 使用Java Mail发送邮件
- 5个砝码 表示1~121
- iOS10 Keychain 使用注意事项
- 高斯消元模板