HDU 5692 Snacks
Posted Pealicx
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了HDU 5692 Snacks相关的知识,希望对你有一定的参考价值。
题目链接【http://acm.hdu.edu.cn/showproblem.php?pid=5692】
题意:一棵树,每个节点有权值,有两种操作:1、修改某个点的权值,2、求以x根的子树中的节点到根的权值和的最大值。
题解:DFS序:对点进行重新编号,每个子树中的所有的节点的编号是连续的。映射到线段树上,进行区间修改,区间查询。
#include<cstdio> #include<cstring> #include<algorithm> using namespace std; typedef long long LL; const int maxn = 1e6 + 15; int T, N, Q; LL a[maxn], sum[maxn]; struct Edge { int to, next; Edge (int to = 0, int next = 0): to(to), next(next) {} } E[maxn * 2]; int head[maxn], tot; void initEdge() { for(int i = 0; i <= N + 15; i++) head[i] = -1; tot = 0; } void addEdge(int u, int v) { E[tot] = Edge(v, head[u]); head[u] = tot++; } int L[maxn], R[maxn], dfs_clock; void DFS(int u, int fa) { L[u] = ++dfs_clock; sum[L[u]] = a[u] + sum[L[fa]]; for(int k = head[u]; ~k; k = E[k].next) { int v = E[k].to; if(v == fa) continue; DFS(v, u); } R[u] = dfs_clock; } LL ma[maxn * 4], fg[maxn * 4]; void Build(int id, int L, int R) { fg[id] = 0; if(L == R) { ma[id] = sum[L]; return ; } int mid = (L + R) >> 1; Build(id << 1, L, mid); Build(id << 1 | 1, mid + 1, R); ma[id] = max(ma[id << 1], ma[id << 1 | 1]); } inline void push_down(int id) { if(fg[id]) { fg[id << 1] += fg[id]; ma[id << 1] += fg[id]; fg[id << 1 | 1] += fg[id]; ma[id << 1 | 1] += fg[id]; fg[id] = 0; } } void update(int id, int L, int R, int l, int r, LL val) { if(L == l && R == r) { fg[id] += val; ma[id] += val; return ; } push_down(id); int mid = (L + R) >> 1; if(r <= mid) update(id << 1, L, mid, l, r, val); else if(l >= mid + 1) update(id << 1 | 1, mid + 1, R, l, r, val); else { update(id << 1, L, mid, l, mid, val); update(id << 1 | 1, mid + 1, R, mid + 1, r, val); } ma[id] = max(ma[id << 1], ma[id << 1 | 1]); } LL query(int id, int L, int R, int l, int r) { if(L == l && R == r) return ma[id]; push_down(id); int mid = (L + R) >> 1; if(r <= mid) return query(id << 1, L, mid, l, r); else if(l >= mid + 1) return query(id << 1 | 1, mid + 1, R, l, r); else { LL t = query(id << 1, L, mid, l, mid); return max(t, query(id << 1 | 1, mid + 1, R, mid + 1, r)); } } int main () { int ic = 0; scanf("%d", &T); while(T--) { scanf("%d %d", &N, &Q); initEdge(); for(int i = 1; i <= N - 1; i++) { int u, v; scanf("%d %d", &u, &v); addEdge(u + 1, v + 1); addEdge(v + 1, u + 1); } for(int i = 1; i <= N; i++) scanf("%lld", &a[i]); dfs_clock = 0, DFS(1, 0); Build(1, 1, N); printf("Case #%d:\n", ++ic); for(int i = 1; i <= Q; i++) { int ty, x; LL y; scanf("%d", &ty); if(ty == 0) { scanf("%d %lld", &x, &y); x++; update(1, 1, N, L[x], R[x], y - a[x]); a[x] = y; } else if(ty == 1) { scanf("%d", &x); x++; LL ans = query(1, 1, N, L[x], R[x]); printf("%lld\n", ans); } } } return 0; }
以上是关于HDU 5692 Snacks的主要内容,如果未能解决你的问题,请参考以下文章