题目链接【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 ;
}

HDU 5692 Snacks的更多相关文章

  1. HDU.5692 Snacks ( DFS序 线段树维护最大值 )

    HDU.5692 Snacks ( DFS序 线段树维护最大值 ) 题意分析 给出一颗树,节点标号为0-n,每个节点有一定权值,并且规定0号为根节点.有两种操作:操作一为询问,给出一个节点x,求从0号 ...

  2. HDU 5692 Snacks bfs版本dfs序 线段树

    Snacks 题目连接: http://acm.hdu.edu.cn/showproblem.php?pid=5692 Description 百度科技园内有n个零食机,零食机之间通过n−1条路相互连 ...

  3. 【DFS序+线段树区间更新区间求最值】HDU 5692 Snacks

    http://acm.hdu.edu.cn/showproblem.php?pid=5692 [思路] 每更新一个点,子树的所有结点都要更新,所以是区间更新 每查询一个点,子树的所有结点都要查询,所以 ...

  4. hdu 5692 Snacks 线段树+dfs

    Snacks Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total Sub ...

  5. hdu 5692 Snacks(dfs时间戳+线段树)

    Snacks Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total Sub ...

  6. HDU 5692 Snacks(DFS序+线段树)

    Snacks Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total Sub ...

  7. Snacks HDU 5692 dfs序列+线段树

    Snacks HDU 5692 dfs序列+线段树 题意 百度科技园内有n个零食机,零食机之间通过n−1条路相互连通.每个零食机都有一个值v,表示为小度熊提供零食的价值. 由于零食被频繁的消耗和补充, ...

  8. hdu 5692(dfs+线段树) Snacks

    题目http://acm.hdu.edu.cn/showproblem.php?pid=5692 题目说每个点至多经过一次,那么就是只能一条路线走到底的意思,看到这题的格式, 多个询问多个更新, 自然 ...

  9. HDU 5692 线段树+dfs序

    Snacks Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total Sub ...

随机推荐

  1. JAVA多线程提高十三:同步集合类的应用

    1.引言 在多线程的环境中,如果想要使用容器类,就需要注意所使用的容器类是否是线程安全的.在最早开始,人们一般都在使用同步容器(Vector,HashTable),其基本的原理,就是针对容器的每一个操 ...

  2. 重构改善既有代码设计--重构手法16:Introduce Foreign Method (引入外加函数)&& 重构手法17:Introduce Local Extension (引入本地扩展)

    重构手法16:Introduce Foreign Method (引入外加函数)你需要为提供服务的类增加一个函数,但你无法修改这个类.在客户类中建立一个函数,并以第一参数形式传入一个服务类实例. 动机 ...

  3. js、php本周第一天和本周最后一天

    PHP:本周一 echo date('Y-m-d',(time()-((date('w')==0?7:date('w'))-1)*24*3600)); //w为星期几的数字形式,这里0为周日 本周日 ...

  4. bzoj 3083 树链剖分

    首先我们先将树提出一个根变成有根树,那么我们可以通过树链剖分来实现对于子树的最小值求解,那么按照当前的根和询问的点的相对位置关系我们可以将询问变成某个子树和或者除去某颗子树之后其余的和,前者直接询问区 ...

  5. 对Feign的请求url 重写

    需求:对当前请求的 url 重新构建 debug feign 的执行可知,重写 LoadBalancerFeignClient 类中的 execute 方法即可控制当前请求的url 代码分析 当引入  ...

  6. java正则: 忽略大小写匹配

    import java.util.regex.Matcher; import java.util.regex.Pattern; import com.sun.org.apache.xerces.int ...

  7. Mysql储存过程6: in / out / inout

    in 为向函数传送进去的值 out 为函数向外返回的值 intout 传送进去的值, 并且还返回这个值 )) begin then select 'true'; else select 'false' ...

  8. ThinkPHP的输出和模型使用

    1.假设在v层需要输出一个变量怎么办呢?即如同在html当中输出php代码. 可以直接使用{$name}代替.花括号被称之为标识符.可以通过修改配置项('TMPL_L_DELIM'=>'< ...

  9. Django 1.10中文文档-第一个应用Part7-自定义管理站点

    开发第一个Django应用,Part7 本教程上接Part6.将继续完成这个投票应用,本节将着重讲解如果用Django自动生成后台管理网站. 自定义管理表单 通过admin.site.register ...

  10. Windows 7 64 位操作系统安装 Ubuntu 17.10

    一.准备工作 1. DiskGenius:分区工具,为 Linux 建立单独的分区.(Linux 公社下载源) 2. UUI:Universal USB Installer,通用 U 盘安装器,用来制 ...