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序+线段树;
首先dfs序映射一下,然后转换成然后线段树维护,新然后开两个数组,一个作为正一个作为负。
复杂度n×log(n);
1 #include<stdio.h> 2 #include<algorithm> 3 #include<queue> 4 #include<stdlib.h> 5 #include<iostream> 6 #include<string.h> 7 #include<set> 8 #include<map> 9 #include<vector> 10 using namespace std; 11 typedef long long LL; 12 int ans[200005]; 13 int id[200005]; 14 int a[200005]; 15 typedef vector<int> Ve; 16 vector<Ve>vec(200005); 17 bool flag[200005]; 18 int cn = 0; 19 int l[200005]; 20 int r[200005]; 21 void dfs(int n,int p); 22 int tree1[200005*4]; 23 int tree2[4*200005]; 24 void update(int x,int n,int c); 25 int ask(int x); 26 int jiou[200005]; 27 void update(int l,int r,int k,int nn,int mm,int co,int p) 28 { 29 if(l > mm||r < nn) 30 { 31 return ; 32 } 33 else if(l <= nn&& r >= mm) 34 { 35 if(p%2)tree1[k]+=co; 36 else tree2[k]+=co; 37 return ; 38 } 39 else 40 { 41 update(l,r,2*k+1,nn,(nn+mm)/2,co,p); 42 update(l,r,2*k+2,(nn+mm)/2+1,mm,co,p); 43 } 44 } 45 int ask1(int l,int r,int k,int nn,int mm) 46 { 47 if(l > mm || r < nn) 48 return 0; 49 else if(l <= nn&&r >= mm) 50 { 51 return tree1[k]; 52 } 53 else 54 { 55 tree1[2*k+1] += tree1[k]; 56 tree1[2*k+2] += tree1[k]; 57 tree1[k] = 0; 58 int nx = ask1(l,r,2*k+1,nn,(nn+mm)/2); 59 int ny = ask1(l,r,2*k+2,(nn+mm)/2+1,mm); 60 return nx + ny; 61 } 62 } 63 int ask2(int l,int r,int k,int nn,int mm) 64 { 65 if(l > mm || r < nn) 66 return 0; 67 else if(l <= nn&&r >= mm) 68 { 69 return tree2[k]; 70 } 71 else 72 { 73 tree2[2*k+1] += tree2[k]; 74 tree2[2*k+2] += tree2[k]; 75 tree2[k] = 0; 76 int nx = ask2(l,r,2*k+1,nn,(nn+mm)/2); 77 int ny = ask2(l,r,2*k+2,(nn+mm)/2+1,mm); 78 return nx + ny; 79 } 80 } 81 int main(void) 82 { 83 int n,m; 84 scanf("%d %d",&n,&m); 85 for(int i = 1; i <= n; i++) 86 { 87 scanf("%d",&a[i]); 88 } 89 for(int i = 1; i < n; i++) 90 { 91 int x,y; 92 scanf("%d %d",&x,&y); 93 vec[x].push_back(y); 94 vec[y].push_back(x); 95 } 96 dfs(1,1); 97 for(int i = 1; i <= n; i++) 98 id[ans[i]] = i; 99 while(m--) 100 { 101 int val; 102 int co,ic; 103 scanf("%d %d",&val,&ic); 104 if(val == 1) 105 { 106 scanf("%d",&co); 107 update(l[ic],r[ic],0,1,cn,co,jiou[ic]); 108 } 109 else 110 { 111 int xx = ask1(id[ic],id[ic],0,1,cn); 112 int yy = ask2(id[ic],id[ic],0,1,cn); 113 //printf("%d ",xx); 114 if(jiou[ic]%2) 115 { 116 printf("%d ",xx-yy+a[ic]); 117 } 118 else printf("%d ",yy-xx+a[ic]); 119 } 120 } 121 return 0; 122 } 123 void dfs(int n,int p) 124 { 125 flag[n] = true; 126 ans[++cn] = n; 127 l[n] = cn; 128 jiou[n] = p; 129 for(int i = 0; i < vec[n].size(); i++) 130 { 131 int x = vec[n][i]; 132 if(!flag[x]) 133 dfs(x,p+1); 134 } 135 r[n] = cn; 136 }