题意:
给你一颗树,现在有两个操作:
1 x val:代表着对节点x进行加val,那么他的孩子节点-val,他的孙子节点+val,依次类推
2 x:代表着你要打印这个节点的值。
思路:
线段树区间更新,单点查询。对于每一个节点,都会有一个对应的控制区间,我们首先DFS一把,找到每个点的控制区间,并且DFS的时候顺便把每一个节点处于什么层次顺便一起记下来。对于该题,我们建立两颗线段树,一颗为奇树,一颗为偶树。对于处于奇数层的节点,我们让它的奇树加,偶树减,同理,处于偶数层的节点,我们让它的偶树加,奇树减,相互不会干扰,并且恰好该节点的应有操作是正确的。
代码:
/*
Algorithm&&Data Structure:Segment Tree && DFS
Source:Codeforces 383C Propagating tree
*/
#define _CRT_SECURE_NO_WARNINGS
#include<cmath>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<map>
#include<iostream>
#include<stdlib.h>
#include<set>
#include<vector>
using namespace std;
#define maxn 200010
#define Lchild rt<<1,L,m
#define Rchild rt<<1|1,m+1,R
#define LL long long
int arr[maxn];
int tree[2][maxn << 2];
LL lazy[2][maxn << 2];
int N,M;
int u, v;
struct node
{
int to,next;
node()
{
to = 0;
next = -1;
}
};
node Edge[maxn << 2];
int count_edge;
int head[maxn];
int dep[maxn], count_dep = 0;
int in[maxn], ou[maxn];
int count_num = 0;
int x, val;
void addedge(int u, int v)
{
Edge[count_edge].to = v;
Edge[count_edge].next = head[u];
head[u] = count_edge;
count_edge++;
}
void dfs(int no,int front)
{
dep[no] = dep[front] + 1;
in[no] = ++count_num;
for (int k = head[no]; k!=-1; k = Edge[k].next)
{
/*if (Edge[k].to == front)
continue;*/
dfs(Edge[k].to,no);
}
ou[no] = count_num;
}
void pushDown(int rt, int o, int len)
{
tree[o][rt << 1] += lazy[o][rt] * (len - (len >> 1));
lazy[o][rt << 1] += lazy[o][rt];
tree[o][rt << 1 | 1] += lazy[o][rt] * (len >> 1);
lazy[o][rt << 1 | 1] += lazy[o][rt];
lazy[o][rt] = 0;
}
void update(int val, int l, int r, int o, int rt = 1, int L = 1, int R = N)
{
if (l <= L&&R <= r)
{
tree[o][rt] += val;
lazy[o][rt] += val;
return;
}
if (lazy[o][rt])
pushDown(rt, o, R - L + 1);
int m = (R + L) >> 1;
if (l <= m)
update(val, l, r, o, Lchild);
if (r>m)
update(val, l, r, o, Rchild);
}
int query(int pos,int o,int rt=1,int L=1,int R=N)
{
if (L == R)
{
return tree[o][rt];
}
if (lazy[o][rt])
pushDown(rt, o, R - L + 1);
int m = (L + R) >> 1;
if (pos <= m)
return query(pos, o, Lchild);
else
return query(pos, o, Rchild);
}
void input()
{
cin >> N >> M;
count_edge = 0;
for (int i = 1; i <= N; i++)
{
scanf("%d", &arr[i]);
}
for (int i = 0; i <= N; i++)
head[i] = -1;
for (int i = 1; i < N; i++)
{
scanf("%d%d", &u, &v);
addedge(u, v);
//addedge(v, u);
}
dep[0] = 0;
dfs(1, 0);
int num;
for (int i = 0; i < M; i++)
{
scanf("%d", &num);
if (num == 1)
{
scanf("%d%d", &x, &val);
update(val, in[x], ou[x], dep[x] & 1);
update(-val, in[x] + 1, ou[x], !(dep[x] & 1));
}
else
{
scanf("%d", &x);
cout << query(in[x], dep[x] & 1) + arr[x] << endl;
}
}
}
int main()
{
input();
return 0;
}