题意:一棵树,两个操作:1.给一个节点加val,下面一层的节点减val,再下面一层加val,以此类推 2.查询某节点的值
思路:dfs序处理,把节点分为奇数层与偶数层。线段树上两个标记,一个是奇数层的、一个偶数层的。这样奇数层的标记传到最底层,如果最底层是奇数层的,那么加上这个值;反之减去。
#include #include #include #include #include #include #include #include #include #include #include #include #include #include #include using namespace std; #define lson(x) 2*x #define rson(x) 2*x+1 typedef long long ll; typedef pair 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; }