题意:一棵树,两个操作:1.给一个节点加val,下面一层的节点减val,再下面一层加val,以此类推 2.查询某节点的值
思路:dfs序处理,把节点分为奇数层与偶数层。线段树上两个标记,一个是奇数层的、一个偶数层的。这样奇数层的标记传到最底层,如果最底层是奇数层的,那么加上这个值;反之减去。
#include<stdio.h>
#include<iostream>
#include<string.h>
#include<string>
#include<stdlib.h>
#include<math.h>
#include<vector>
#include<list>
#include<map>
#include<set>
#include<stack>
#include<queue>
#include<algorithm>
#include<numeric>
#include<functional>
using namespace std;
#define lson(x) 2*x
#define rson(x) 2*x+1
typedef long long ll;
typedef pair<int,int> pii;
const int maxn = 200005;
int in[maxn],out[maxn],point[maxn];
struct Edge
{
int to,next;
}edge[2*maxn];
int head[maxn],tot,t,vis[maxn];
int a[maxn],num[maxn];
int chen[maxn];
struct data
{
int l,r,p;
int laz0,laz1,num;
}node[maxn*4];
void init()
{
memset(head,-1,sizeof head);
memset(vis,0,sizeof vis);
tot = 0;
t = 0;
}
void add(int x,int y)
{
edge[tot].to = y;
edge[tot].next = head[x];
head[x] = tot++;
}
void dfs(int x,int k)
{
vis[x] = 1;
in[x] = ++t;
num[t] = a[x];
point[t] = x;
chen[x] = k;
for(int i = head[x]; i != -1; i = edge[i].next)
{
int y = edge[i].to;
if(vis[y]) continue;
dfs(y,k^1);
}
out[x] = t;
}
void down(int cnt)
{
if(node[cnt].laz0 == 0 && node[cnt].laz1 == 0) return;
int tg0 = node[cnt].laz0;
int tg1 = node[cnt].laz1;
node[lson(cnt)].laz0 += tg0;
node[lson(cnt)].laz1 += tg1;
node[rson(cnt)].laz0 += tg0;
node[rson(cnt)].laz1 += tg1;
if(node[lson(cnt)].p)
{
if(chen[node[lson(cnt)].p] == 0)
node[lson(cnt)].num += tg0 - tg1;
else
node[lson(cnt)].num += tg1 - tg0;
}
if(node[rson(cnt)].p)
{
if(chen[node[rson(cnt)].p] == 0)
node[rson(cnt)].num += tg0 - tg1;
else
node[rson(cnt)].num += tg1 - tg0;
}
node[cnt].laz0 = 0;
node[cnt].laz1 = 0;
}
void build(int x,int y, int cnt)
{
node[cnt].l = x;
node[cnt].r = y;
node[cnt].laz0 = 0;
node[cnt].laz1 = 0;
node[cnt].p = 0;
if(x == y)
{
node[cnt].p = point[x];
node[cnt].num = num[x];
return;
}
int mid = (x+y) / 2;
build(x,mid,lson(cnt));
build(mid+1,y,rson(cnt));
}
void up(int x,int y,int cnt,int val,int k)
{
if(x == node[cnt].l && y == node[cnt].r)
{
if(k == 0)
{
node[cnt].laz0 += val;
if(node[cnt].p)
{
if(chen[node[cnt].p] == 0)
node[cnt].num += val;
else
node[cnt].num -= val;
}
}
else
{
node[cnt].laz1 += val;
if(node[cnt].p)
{
if(chen[node[cnt].p] == 1)
node[cnt].num += val;
else
node[cnt].num -= val;
}
}
return;
}
down(cnt);
int mid = (node[cnt].l + node[cnt].r) / 2;
if(y <= mid)
up(x,y,lson(cnt),val,k);
else if(x >= mid+1)
up(x,y,rson(cnt),val,k);
else
{
up(x,mid,lson(cnt),val,k);
up(mid+1,y,rson(cnt),val,k);
}
}
int fid(int x,int y,int cnt)
{
if(x == node[cnt].l && y == node[cnt].r)
{
return node[cnt].num;
}
down(cnt);
int mid = (node[cnt].l + node[cnt].r) / 2;
if(y <= mid)
return fid(x,y,lson(cnt));
else if(x >= mid+1)
return fid(x,y,rson(cnt));
}
int main(void)
{
int n,m;
while(scanf("%d%d",&n,&m)!=EOF)
{
init();
for(int i = 1; i <= n; i++)
scanf("%d",&a[i]);
for(int i = 1; i < n; i++)
{
int x,y;
scanf("%d%d",&x,&y);
add(x,y);
add(y,x);
}
dfs(1,0);
build(1,n,1);
while(m--)
{
int op,x,val;
scanf("%d%d",&op,&x);
if(op == 1)
{
scanf("%d",&val);
up(in[x],out[x],1,val,chen[x]);
}
else
printf("%d\n",fid(in[x],in[x],1));
}
}
return 0;
}