首页 > 代码库 > HDU 5692 Snacks
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
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。