题目链接【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 + ;
int T, N, Q;
LL a[maxn], sum[maxn];
struct Edge
{
int to, next;
Edge (int to = , int next = ): to(to), next(next) {}
} E[maxn * ];
int head[maxn], tot;
void initEdge()
{
for(int i = ; i <= N + ; i++) head[i] = -;
tot = ;
}
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 * ], fg[maxn * ];
void Build(int id, int L, int R)
{
fg[id] = ;
if(L == R)
{
ma[id] = sum[L];
return ;
}
int mid = (L + R) >> ;
Build(id << , L, mid);
Build(id << | , mid + , R);
ma[id] = max(ma[id << ], ma[id << | ]);
}
inline void push_down(int id)
{
if(fg[id])
{
fg[id << ] += fg[id];
ma[id << ] += fg[id];
fg[id << | ] += fg[id];
ma[id << | ] += fg[id];
fg[id] = ;
}
}
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) >> ;
if(r <= mid)
update(id << , L, mid, l, r, val);
else if(l >= mid + )
update(id << | , mid + , R, l, r, val);
else
{
update(id << , L, mid, l, mid, val);
update(id << | , mid + , R, mid + , r, val);
}
ma[id] = max(ma[id << ], ma[id << | ]);
}
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) >> ;
if(r <= mid)
return query(id << , L, mid, l, r);
else if(l >= mid + )
return query(id << | , mid + , R, l, r);
else
{
LL t = query(id << , L, mid, l, mid);
return max(t, query(id << | , mid + , R, mid + , r));
}
}
int main ()
{
int ic = ;
scanf("%d", &T);
while(T--)
{
scanf("%d %d", &N, &Q);
initEdge();
for(int i = ; i <= N - ; i++)
{
int u, v;
scanf("%d %d", &u, &v);
addEdge(u + , v + );
addEdge(v + , u + );
}
for(int i = ; i <= N; i++) scanf("%lld", &a[i]);
dfs_clock = , DFS(, );
Build(, , N);
printf("Case #%d:\n", ++ic);
for(int i = ; i <= Q; i++)
{
int ty, x;
LL y;
scanf("%d", &ty);
if(ty == )
{
scanf("%d %lld", &x, &y);
x++;
update(, , N, L[x], R[x], y - a[x]);
a[x] = y;
}
else if(ty == )
{
scanf("%d", &x);
x++;
LL ans = query(, , N, L[x], R[x]);
printf("%lld\n", ans);
}
}
}
return ;
}

最新文章

  1. C#基础篇 - 正则表达式入门
  2. ms-dos中 MSCDEX命名语法详解
  3. word20161213
  4. 冰球项目日志3-yjw
  5. iOS开发中调试小技巧
  6. Multipart/form-data POST文件上传详解
  7. Codeforces Round #294 (Div. 2)
  8. JAVA中在Myeclipse里把表导入成相应的poco实体类
  9. C 栈实例
  10. 深入理解OAuth2.0
  11. 用excel打造报表查询系统
  12. 使用python操作RabbitMQ,Redis,Memcache,SQLAlchemy 其二
  13. mongodb中limit与skip方法
  14. C# 如何解决 引用的两个同名同版本的DLL冲突
  15. linux增加,删除用户组,解压缩命令,VIM使用命令
  16. springboot restful接口服务异常处理
  17. WEBSHELL恶意代码批量提取清除工具
  18. 打开网页直接弹出qq对话框?
  19. 正则表达式——WPF输入控件TextBox 限定输入特定字符
  20. 转载:canal数据库同步redis

热门文章

  1. .NET面试题系列(二)GC
  2. IDEA 启动时,报“淇℃伅”的字符
  3. Tool1—安装配置Windows Live Writer
  4. python模块之StringIO/cStringIO(内存文件)
  5. oracle 归档模式、补充日志
  6. python开发规范(转载)
  7. javascript反混淆之packed混淆(一)
  8. 链接 DB App.config 解析
  9. selenium滚动到顶部与底部
  10. NGUI优化之Drawcall