codeforces 383C Propagating tree 线段树
2015-12-01 10:57
387 查看
http://codeforces.com/problemset/problem/383/C
题目就是说, 给一棵树,将一个节点的值+val, 那么它的子节点都会-val, 子节点的子节点+val........这样类推, 给一系列操作,2是查询一个节点的值, 1是将一个节点的值+val。
首先,<dfs一遍求出dfs序以及每个点的深度, 然后建两颗线段树, 深度为奇数的建一棵, 偶数建一棵。 改变一个节点的值, 就把与他奇偶相同的那颗树全都+val, 不同的全都-val。 具体看代码>.....
题目就是说, 给一棵树,将一个节点的值+val, 那么它的子节点都会-val, 子节点的子节点+val........这样类推, 给一系列操作,2是查询一个节点的值, 1是将一个节点的值+val。
首先,<dfs一遍求出dfs序以及每个点的深度, 然后建两颗线段树, 深度为奇数的建一棵, 偶数建一棵。 改变一个节点的值, 就把与他奇偶相同的那颗树全都+val, 不同的全都-val。 具体看代码>.....
#include<bits/stdc++.h> using namespace std; #define pb(x) push_back(x) #define ll long long #define mk(x, y) make_pair(x, y) #define lson l, m, rt<<1 #define mem(a) memset(a, 0, sizeof(a)) #define rson m+1, r, rt<<1|1 #define mem1(a) memset(a, -1, sizeof(a)) #define mem2(a) memset(a, 0x3f, sizeof(a)) #define rep(i, a, n) for(int i = a; i<n; i++) #define ull unsigned long long typedef pair<int, int> pll; const double PI = acos(-1.0); const double eps = 1e-8; const int mod = 1e9+7; const int inf = 1061109567; const int dir[][2] = { {-1, 0}, {1, 0}, {0, -1}, {0, 1} }; const int maxn = 2e5+5; int in[maxn], out[maxn], num, val[maxn], head[maxn], dis[maxn], dfs_clock; int cnt[maxn<<2][2]; struct node { int to, nextt; }e[maxn*2]; void add(int u, int v) { e[num].to = v; e[num].nextt = head[u]; head[u] = num++; } void dfs(int u, int fa) { dis[u] = dis[fa]+1; in[u] = ++dfs_clock; for(int i = head[u]; ~i; i = e[i].nextt) { int v = e[i].to; if(v == fa) continue; dfs(v, u); } out[u] = dfs_clock; } void pushDown(int rt, int sign) { if(cnt[rt][sign]) { cnt[rt<<1][sign] += cnt[rt][sign]; cnt[rt<<1|1][sign] += cnt[rt][sign]; cnt[rt][sign] = 0; } } void update(int L, int R, int l, int r, int rt, int val, int sign) { if(L<=l && R>=r) { cnt[rt][sign] += val; return ; } pushDown(rt, sign); int m = l+r>>1; if(L<=m) update(L, R, lson, val, sign); if(R>m) update(L, R, rson, val, sign); } int query(int p, int l, int r, int rt, int sign) { if(l == r) { return cnt[rt][sign]; } pushDown(rt, sign); int m = l+r>>1; int ret = 0; if(p<=m) return query(p, lson, sign); else return query(p, rson, sign); } int main() { int n, m, x, y, z; cin>>n>>m; for(int i = 1; i<=n; i++) { scanf("%d", &val[i]); } mem1(head); for(int i = 0; i<n-1; i++) { scanf("%d%d", &x, &y); add(x, y); add(y, x); } dis[0] = 0; dfs(1, 0); while(m--) { scanf("%d", &z); if(z == 2) { scanf("%d", &x); printf("%d\n", query(in[x], 1, n, 1, dis[x]&1)+val[x]); } else { scanf("%d%d", &x, &y); update(in[x], out[x], 1, n, 1, y, dis[x]&1); update(in[x], out[x], 1, n, 1, -y, !(dis[x]&1)); } } }
相关文章推荐
- Linux下获取虚拟地址对应的物理地址的方法
- 每天一个linux命令(18):find 命令概览
- 每天一个linux命令(17):locate 命令
- 树莓派2中webiopi项目的适配
- 每天一个linux命令(16):whereis 命令
- linux GCC gdb 入门级常用指令以及参数
- Linux 分区注意事项
- hadoop中联结不同来源数据
- 每天一个linux命令(15):whereis 命令
- 解决OPPO手机adb调试找不到设备(Win8系统)
- 每天一个linux命令(14):which命令
- LVS+Keepalived实现高可用负载均衡
- 每天一个linux命令(13):tail 命令
- 架构-项目管理-jenkins
- CentOS7 安装 swoole
- 多线程技术 NSThread & NSOperation & GCD
- 每天一个linux命令(12):head 命令
- nginx的负载均衡集群
- 每天一个linux命令(11):less 命令
- org.apache.commons.lang3.StringUtils