【DFS序+树状数组】#144. DFS 序 1
每个点记录一个进入的时间和出来的时间
这样就能保证每个子树内的点的顺序是连着的
然后就可以利用树状数组维护单点修改,区间查询了
代码
#include<bits/stdc++.h> using namespace std; const int maxn=1e6+5; int n,m,root,cnt,times; int v[maxn],l[maxn],r[maxn],head[maxn]; long long c[maxn]; struct edge { int to,nxt; }e[maxn<<2]; void add(int x,int y) { e[++cnt].to=y; e[cnt].nxt=head[x]; head[x]=cnt; } int lowbit(int x) { return x&(-x); } void modify(int x,int val) { for(;x<=n;x+=lowbit(x)) c[x]+=val; } void dfs(int u,int fa) { l[u]=++times; modify(l[u],v[u]); for(int i=head[u];i;i=e[i].nxt) { int to=e[i].to; if(to==fa) continue; dfs(to,u); } r[u]=times; } long long query(int x) { long long res=0; for(;x>=1;x-=lowbit(x)) res+=c[x]; return res; } int main() { freopen("a.in","r",stdin); freopen("a.out","w",stdout); scanf("%d%d%d",&n,&m,&root); for(int i=1;i<=n;i++) scanf("%d",&v[i]); int x,y; for(int i=1;i<n;i++) { scanf("%d%d",&x,&y); add(x,y); add(y,x); } dfs(root,0); for(int i=1;i<=m;i++) { int op; scanf("%d",&op); if(op==1) { scanf("%d%d",&x,&y); modify(l[x],y); } else { scanf("%d",&x); printf("%lld\n",query(r[x])-query(l[x]-1)); } } return 0; }