AC日记——Propagating tree Codeforces 383c
Iahub likes trees very much. Recently he discovered an interesting tree named propagating tree. The tree consists of n nodes numbered from 1 to n, each node i having an initial value ai. The root of the tree is node 1.
This tree has a special property: when a value val is added to a value of node i, the value -val is added to values of all the children of node i. Note that when you add value -val to a child of node i, you also add -(-val) to all children of the child of node i and so on. Look an example explanation to understand better how it works.
This tree supports two types of queries:
- "1 x val" — val is added to the value of node x;
- "2 x" — print the current value of node x.
In order to help Iahub understand the tree better, you must answer m queries of the preceding type.
The first line contains two integers n and m (1 ≤ n, m ≤ 200000). The second line contains n integers a1, a2, ..., an (1 ≤ ai ≤ 1000). Each of the next n–1 lines contains two integers vi and ui (1 ≤ vi, ui ≤ n), meaning that there is an edge between nodes vi and ui.
Each of the next m lines contains a query in the format described above. It is guaranteed that the following constraints hold for all queries: 1 ≤ x ≤ n, 1 ≤ val ≤ 1000.
For each query of type two (print the value of node x) you must print the answer to the query on a separate line. The queries must be answered in the order given in the input.
5 5
1 2 1 1 2
1 2
1 3
2 4
2 5
1 2 3
1 1 2
2 1
2 2
2 4
3
3
0
The values of the nodes are [1, 2, 1, 1, 2] at the beginning.
Then value 3 is added to node 2. It propagates and value -3 is added to it's sons, node 4 and node 5. Then it cannot propagate any more. So the values of the nodes are [1, 5, 1, - 2, - 1].
Then value 2 is added to node 1. It propagates and value -2 is added to it's sons, node 2 and node 3. From node 2 it propagates again, adding value 2 to it's sons, node 4 and node 5. Node 3 has no sons, so it cannot propagate from there. The values of the nodes are[3, 3, - 1, 0, 1].
You can see all the definitions about the tree at the following link: http://en.wikipedia.org/wiki/Tree_(graph_theory)
思路;
dfs序同时处理深度,然后搞搞就a了;
来,上代码:
#include <cstdio> #include <cstring> #include <iostream> #include <algorithm> #define maxn 200005 #define LL long long using namespace std; struct EdgeType { int v,e; }; struct EdgeType edge[maxn<<1]; struct TreeNodeType { int l,r,dis,mid,flag; }; struct TreeNodeType tree[maxn<<2]; int if_z,n,m,dis[maxn],head[maxn]; int cnt,f[maxn],li[maxn],ri[maxn]; int id[maxn],dis_[maxn],type,x,ans; bool deep[maxn]; char Cget; inline void in(int &now) { now=0,if_z=1,Cget=getchar(); while(Cget>'9'||Cget<'0') { if(Cget=='-') if_z=-1; Cget=getchar(); } while(Cget>='0'&&Cget<='9') { now=now*10+Cget-'0'; Cget=getchar(); } now*=if_z; } void search_1(int now,int fa) { deep[now]=!deep[fa],f[now]=fa; id[now]=++cnt,li[now]=cnt,dis_[cnt]=dis[now]; if(!deep[now]) dis_[cnt]*=-1; for(int i=head[now];i;i=edge[i].e) { if(edge[i].v==f[now]) continue; search_1(edge[i].v,now); } ri[now]=cnt; } void tree_build(int now,int l,int r) { tree[now].l=l,tree[now].r=r; if(l==r) { tree[now].dis=dis_[l]; return ; } tree[now].mid=(l+r)>>1; tree_build(now<<1,l,tree[now].mid); tree_build(now<<1|1,tree[now].mid+1,r); } void tree_do(int now,int l,int r) { if(tree[now].l==l&&tree[now].r==r) { if(type==1) { tree[now].flag+=x; if(l==r) tree[now].dis+=x; } else ans+=tree[now].dis; return ; } if(tree[now].flag) { tree[now<<1].flag+=tree[now].flag; tree[now<<1|1].flag+=tree[now].flag; if(tree[now<<1].l==tree[now<<1].r) tree[now<<1].dis+=tree[now].flag; if(tree[now<<1|1].l==tree[now<<1|1].r) tree[now<<1|1].dis+=tree[now].flag; tree[now].flag=0; } if(l>tree[now].mid) tree_do(now<<1|1,l,r); else if(r<=tree[now].mid) tree_do(now<<1,l,r); else { tree_do(now<<1,l,tree[now].mid); tree_do(now<<1|1,tree[now].mid+1,r); } } int main() { in(n),in(m);int u,v; for(int i=1;i<=n;i++) in(dis[i]); for(int i=1;i<n;i++) { in(u),in(v); edge[++cnt].v=v,edge[cnt].e=head[u],head[u]=cnt; edge[++cnt].v=u,edge[cnt].e=head[v],head[v]=cnt; } cnt=0,search_1(1,0); tree_build(1,1,n); while(m--) { in(type),in(u); if(type==1) { in(x); if(!deep[u]) x*=-1; tree_do(1,li[u],ri[u]); } else { ans=0; tree_do(1,li[u],li[u]); if(!deep[u]) ans*=-1; printf("%d\n",ans); } } return 0; }