思维水题 每个区间维护两个值 一个是来自偶数层节点的累加值 另一个是来自奇数层节点的累加值
因为是单点查询 pushup和pushdown都扔掉就 一路加到底即可
#include <bits/stdc++.h> using namespace std; struct node1 { int v; int next; }; struct node2 { int l; int r; int val[2]; }; node1 edge[400010]; node2 tree[800010]; int pre[200010],first[200010],deep[200010],mp[200010],sum[200010]; int n,q,num,ans; void addedge(int u,int v) { edge[num].v=v; edge[num].next=first[u]; first[u]=num++; return; } void build(int l,int r,int cur) { int m; tree[cur].l=l; tree[cur].r=r; tree[cur].val[0]=0; tree[cur].val[1]=0; if(l==r) return; m=(l+r)/2; build(l,m,2*cur); build(m+1,r,2*cur+1); return; } void dfs(int cur,int fa) { int i,v; mp[cur]=++num,sum[cur]=1; for(i=first[cur];i!=-1;i=edge[i].next) { v=edge[i].v; if(v!=fa) { deep[v]=deep[cur]+1; dfs(v,cur); sum[cur]+=sum[v]; } } return; } void update(int pl,int pr,int dep,int val,int cur) { if(pl<=tree[cur].l&&tree[cur].r<=pr) { tree[cur].val[dep]+=val; return; } if(pl<=tree[2*cur].r) update(pl,pr,dep,val,2*cur); if(pr>=tree[2*cur+1].l) update(pl,pr,dep,val,2*cur+1); return; } void query(int tar,int dep,int cur) { if(dep) ans+=(tree[cur].val[1]-tree[cur].val[0]); else ans+=(tree[cur].val[0]-tree[cur].val[1]); if(tree[cur].l==tree[cur].r) return; if(tar<=tree[2*cur].r) query(tar,dep,2*cur); else query(tar,dep,2*cur+1); return; } int main() { int i,u,v,op,val; scanf("%d%d",&n,&q); for(i=1;i<=n;i++) { scanf("%d",&pre[i]); } build(1,n,1); memset(first,-1,sizeof(first)); num=0; for(i=1;i<=n-1;i++) { scanf("%d%d",&u,&v); addedge(u,v); addedge(v,u); } deep[1]=1; num=0; dfs(1,-1); while(q--) { scanf("%d",&op); if(op==1) { scanf("%d%d",&u,&val); update(mp[u],mp[u]+sum[u]-1,deep[u]%2,val,1); } else { scanf("%d",&u); ans=pre[u]; query(mp[u],deep[u]%2,1); printf("%d\n",ans); } } return 0; }