标签:acm c++ dfs 数据结构 codeforces
#include <iostream> #include <cstdio> #include <vector> #include <algorithm> #define N 200020 using namespace std; struct ee//存储需要修改哪些区间的结构体 { int x1,y1,x2,y2; }e[N]; vector<int> g[N]; int n,m,a[N],d[N],c[N],bef[N],index=1; void dfs1(int x,int fa,int deep)//处理d[]数组 { d[x]=deep; for(int i=0;i<g[x].size();i++) if(g[x][i]!=fa) dfs1(g[x][i],x,1-deep); } void dfs2(int x,int fa,int deep)//得到新数组 { if(d[x]==deep) bef[x]=index++;//aft[index++]=x;//bef[i] 其中,i是原节点的编号,bef[i]是i在新数组中的下标 for(int i=0;i<g[x].size();i++) if(g[x][i]!=fa) dfs2(g[x][i],x,deep); } void dfs3(int x,int fa)//预处理每个点的属性 { for(int i=0;i<g[x].size();i++) if(g[x][i]!=fa) dfs3(g[x][i],x); int ma1=bef[x],mi2=N,ma2=0; for(int i=0;i<g[x].size();i++) { if(g[x][i]==fa) continue; int cur=g[x][i]; mi2=min(mi2,e[cur].x1); ma2=max(ma2,e[cur].y1); ma1=max(ma1,e[cur].y2); } e[x].x1=bef[x],e[x].y1=ma1,e[x].x2=mi2,e[x].y2=ma2;//[x1,y1]为需要加值操作的区间,[x2,y2]为需要减值操作的区间,可以由儿子确定 } int getnum(int x)//下面便是树状数组的区间修改,点查询函数咯~ { int rnt=0; for(int i=x;i<=n;i+=(i&(-i))) { rnt+=c[i]; } return rnt; } void add(int i,int a) { while(i>=1) { c[i]+=a; i-=(i&(-i)); } } int main() { scanf("%d%d",&n,&m); for(int i=1;i<=n;i++) scanf("%d",a+i); for(int i=0;i<n-1;i++) { int a,b; scanf("%d%d",&a,&b); g[a].push_back(b),g[b].push_back(a); } dfs1(1,0,1);//计算d[]数组 dfs2(1,0,1);//对根节点进行处理 for(int i=0;i<g[1].size();i++) dfs2(g[1][i],1,0);//对根节点的每个儿子进行处理 dfs3(1,0);//预处理 while(m--) { int ty; scanf("%d",&ty); if(ty==1) { int x,y; scanf("%d%d",&x,&y); int l1=e[x].x1,r1=e[x].y1,l2=e[x].x2,r2=e[x].y2; add(r1,y),add(l1-1,-y); if(r2!=0) add(r2,-y),add(l2-1,y);//如果不是根节点再进行减操作 } else { int x; scanf("%d",&x); cout<<getnum(bef[x])+a[x]<<endl; } } return 0; }
Codeforces 383C . Propagating tree【树状数组,dfs】
标签:acm c++ dfs 数据结构 codeforces
原文地址:http://blog.csdn.net/u013912596/article/details/38952557