CodeForces - 383C Propagating tree (DFS序+线段树)
2017-08-12 10:31
288 查看
题意:
n个结点的树,以1为根,给出结点的权值。有两种操作:
1.从某个结点开始使其权值 + v ,并将他的儿子结点 - v ,再将他的儿子的儿子结点 + v,...............,如此操作到叶子结点。
2.查询某点的值
思路:
显然,操作一是指 对深度奇偶性一致的子结点做 + ,不一致的做 - 。
所以我们可以根据结点深度的奇偶性,通过DFS序建立两颗线段树。将操作一和二化为线段树区间修改,单点查询的操作。
注意特判只有一个根结点的情况。
代码:
n个结点的树,以1为根,给出结点的权值。有两种操作:
1.从某个结点开始使其权值 + v ,并将他的儿子结点 - v ,再将他的儿子的儿子结点 + v,...............,如此操作到叶子结点。
2.查询某点的值
思路:
显然,操作一是指 对深度奇偶性一致的子结点做 + ,不一致的做 - 。
所以我们可以根据结点深度的奇偶性,通过DFS序建立两颗线段树。将操作一和二化为线段树区间修改,单点查询的操作。
注意特判只有一个根结点的情况。
代码:
#include <bits/stdc++.h> using namespace std; #define ls l,mid,rt*2,k #define rs mid+1,r,rt*2+1,k #define sf rt,k #define mi (l+r)/2 const int MAXN=2e5+7; vector <int> edge[MAXN]; int n,m,a[MAXN]; int order[2][MAXN],depth[MAXN],in[2][MAXN],out[2][MAXN],cnt[2]; int ppp[2],tree[2][MAXN*4],lazy[2][MAXN*4]; int st,en,v; void dfs(int pos,int dep){ depth[pos]=dep; int k=dep%2; cnt[k]++; order[k][cnt[k]]=pos; in[k][pos]=cnt[k]; in[!k][pos]=cnt[!k]+1; int len=edge[pos].size(); for(int i=0;i<len;i++) dfs(edge[pos][i],dep+1); out[k][pos]=cnt[k]; out[!k][pos]=cnt[!k]; } void push_down(int rt,int k){ if(lazy[k][rt]!=0){ lazy[k][rt*2]+=lazy[k][rt]; lazy[k][rt*2+1]+=lazy[k][rt]; } lazy[k][rt]=0; } void build(int l,int r,int rt,int k){ lazy[k][rt]=0; if(l==r){ tree[k][rt]=a[order[k][++ppp[k]]]; return ; } int mid=mi; build(ls); build(rs); } void update(int l,int r,int rt,int k){ if(l>en||r<st) return ; if(st<=l&&r<=en){ lazy[k][rt]+=v; return ; } int mid=mi; push_down(sf); update(ls);update(rs); } void query(int l,int r,int rt,int k){ if(l>en||r<st) return ; if(l==r){ v=tree[k][rt]+lazy[k][rt]; return ; } int mid=mi; push_down(sf); query(ls);query(rs); } int main(){ int x,y,op; while(scanf("%d%d",&n,&m)!=-1){ for(int i=1;i<=n;i++) scanf("%d",&a[i]),edge[i].clear(); for(int i=1;i<n;i++){ scanf("%d%d",&x,&y); edge[x].push_back(y); } if(n==1){ while(m--){ scanf("%d",&op); if(op==1){ scanf("%d%d",&x,&y); a[x]+=y; }else{ scanf("%d",&x); printf("%d\n",a[x]); } } }else{ cnt[0]=cnt[1]=0; dfs(1,1); ppp[0]=ppp[1]=0; build(1,cnt[0],1,0); build(1,cnt[1],1,1); while(m--){ scanf("%d",&op); if(op==1){ scanf("%d%d",&x,&y); int k=depth[x]%2; st=in[k][x],en=out[k][x],v=y; update(1,cnt[k],1,k); st=in[!k][x],en=out[!k][x],v=-y; if(st<=en) update(1,cnt[!k],1,!k); }else{ scanf("%d",&x); int k=depth[x]%2; st=en=in[k][x]; query(1,cnt[k],1,k); printf("%d\n",v); } } } } }
相关文章推荐
- CodeForces 620E:New Year Tree(dfs序+线段树)
- codeforces 208 E. Blood Cousins (dsu on the tree)
- Codeforces 280C Game on Tree 树形期望dp
- codeforces 902 B. Coloring a Tree
- 【CodeForces 614A】Link/Cut Tree
- Codeforces 711C. Bear and Tree Jumps【树形dp好题】
- codeforces 690 F3 Tree of Life (hard) 树hash
- Codeforces 618 D Hamiltonian Spanning Tree 贪心+dp
- 【CodeForces】915 F. Imbalance Value of a Tree 并查集
- 【Monotonic-queue】【dp】【Segment-tree】【STL】Codeforces 487B - Strip
- Codeforces 429 A. Xor-tree
- 【13.91%】【codeforces 593D】Happy Tree Party
- Codeforces 461 B. Appleman and Tree
- 【 Codeforces 514E 】Darth Vader and Tree - DP 矩乘转移
- codeforces 812 E. Sagheer and Apple Tree(树上博弈)
- 【CodeForces】600 E. Lomsat gelral (dsu on tree)
- Codeforces 739B Alyona and a tree
- Codeforces 842C - Ilya And The Tree 【树上DFS】
- cf-edu#6- E - New Year Tree -dfs序+线段树维护
- Codeforces 383C. Propagating tree(树上hash映射+线段树懒操作)->(一种将树结点规律化的方法)