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

题意分析

给出一颗树,节点标号为0-n,每个节点有一定权值,并且规定0号为根节点。有两种操作:操作一为询问,给出一个节点x,求从0号节点开始到x节点,所能经过的路径的权值最大为多少;操作二为修改,给出一个节点x和值val,将x的权值改为val.

可以看出是树上修改问题。考虑的解题方式有DFS序+线段树,树链剖分,CXTree。由于后两种目前还不会,选择用DFS序来解决。

首先对树求DFS序,在求解过程当中,顺便求解树上前缀和(prefix数组),并保存从树上节点到DFS序的hash值(hashbcak数组),然后根据这两个数组来讲建树。

之后查询和修改时,根据已经求得的dfs序,定位到对应区间来修改即可。

注意线段树的权值域、lazy域等保存节点权值的数据以及线段树的查询,修改权值的时候,要用__int64.

在求区间最大值的时候,不要无脑递归子树,要分开求解,长个心眼。

代码总览

#include <bits/stdc++.h>
#define nmax 200005
#define ll __int64
using namespace std;
struct edge{
int to;
int next;
}edg[nmax<<1];
struct tree{
int l,r;
ll lazy,val;
int mid(){
return (l+r)>>1;
}
}tree[nmax<<2];
int head[nmax],tot,times,in[nmax],out[nmax],hashback[nmax];
ll prefix[nmax],snake[nmax];
void add(int u, int v){
edg[tot].to = v;
edg[tot].next = head[u];
head[u] = tot++;
}
void init(){
memset(head,-1,sizeof head);
memset(tree,0,sizeof tree);
memset(edg,0,sizeof edg);
memset(snake,0,sizeof snake);
memset(prefix,0,sizeof prefix);
memset(hashback,0,sizeof hashback);
tot = 0;
times = 0;
}
void dfs(int rt, int f){
times++;
in[rt] = times;
prefix[rt] = snake[rt]+prefix[f];
hashback[times] = rt;
for(int i = head[rt]; i!=-1; i = edg[i].next){
int nxt = edg[i].to;
if(nxt != f){
dfs(nxt,rt);
}
}
out[rt] = times;
}
void PushUp(int rt)
{
tree[rt].val = max(tree[rt<<1].val , tree[rt<<1|1].val);
}
void PushDown(int rt)
{
if(tree[rt].lazy){
tree[rt<<1].lazy += tree[rt].lazy;
tree[rt<<1|1].lazy += tree[rt].lazy;
tree[rt<<1].val += tree[rt].lazy;
tree[rt<<1|1].val +=tree[rt].lazy;
tree[rt].lazy = 0;
}
}
void Build(int l, int r, int rt){
tree[rt].l = l; tree[rt].r = r;
tree[rt].val = tree[rt].lazy = 0;
if(l == r){
tree[rt].val = prefix[hashback[l]];
return;
}
Build(l,tree[rt].mid(),rt<<1);
Build(tree[rt].mid()+1,r,rt<<1|1);
PushUp(rt);
}
void UpdateInterval(ll val, int l, int r, int rt){
if(tree[rt].l >r || tree[rt].r < l) return;
if(tree[rt].l >= l && tree[rt].r <= r){
tree[rt].val += val ;
tree[rt].lazy += val;
return;
}
PushDown(rt);
UpdateInterval(val,l,r,rt<<1) ;
UpdateInterval(val,l,r,rt<<1|1);
PushUp(rt);
}
ll Query(int l,int r,int rt){
if(l <= tree[rt].l && tree[rt].r <= r) return tree[rt].val;
PushDown(rt);
ll ans = -1e18;
if(l <= tree[rt].mid()) ans = max(ans,Query(l,r,rt<<1));
if(r > tree[rt].mid()) ans = max(ans,Query(l,r,rt<<1|1));
return ans;
}
int t,n,m;
int main(){
scanf("%d",&t);
for(int kase = 1;kase<=t;kase++){
printf("Case #%d:\n",kase);
init();
scanf("%d %d",&n,&m);
int u,v,x,op;
ll val;
for(int i = 0;i<n-1;++i){
scanf("%d %d",&u,&v);
u++,v++;
add(u,v),add(v,u);
}
for(int i = 1;i<=n;++i) scanf("%I64d",&snake[i]);
prefix[0] = 0;
dfs(1,0);
Build(1,times,1);
for(int i = 0;i<m;++i){
scanf("%d",&op);
if(op == 1){
scanf("%d",&x);
x++;
printf("%I64d\n",Query(in[x],out[x],1));
}else{
scanf("%d %I64d",&x,&val);
x++;
ll change = val - snake[x];
UpdateInterval(change,in[x],out[x],1);
snake[x] = val;
}
}
}
return 0;
}

HDU.5692 Snacks ( DFS序 线段树维护最大值 )的更多相关文章

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

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

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

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

  3. HDU5692 Snacks DFS序 线段树

    去博客园看该题解 题目 HDU5692 Snacks Problem Description 百度科技园内有n个零食机,零食机之间通过n−1条路相互连通.每个零食机都有一个值v,表示为小度熊提供零食的 ...

  4. hdu-5692 Snacks(dfs序+线段树)

    题目链接: Snacks Problem Description   百度科技园内有n个零食机,零食机之间通过n−1条路相互连通.每个零食机都有一个值v,表示为小度熊提供零食的价值. 由于零食被频繁的 ...

  5. Assign the task HDU - 3974(dfs序+线段树)

    There is a company that has N employees(numbered from 1 to N),every employee in the company has a im ...

  6. HDU 4366 Successor( DFS序+ 线段树 )

    Successor Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total S ...

  7. 【BZOJ-3252】攻略 DFS序 + 线段树 + 贪心

    3252: 攻略 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 339  Solved: 130[Submit][Status][Discuss] D ...

  8. Codeforces 343D Water Tree(DFS序 + 线段树)

    题目大概说给一棵树,进行以下3个操作:把某结点为根的子树中各个结点值设为1.把某结点以及其各个祖先值设为0.询问某结点的值. 对于第一个操作就是经典的DFS序+线段树了.而对于第二个操作,考虑再维护一 ...

  9. POJ 3321 DFS序+线段树

    单点修改树中某个节点,查询子树的性质.DFS序 子树序列一定在父节点的DFS序列之内,所以可以用线段树维护. 1: /* 2: DFS序 +线段树 3: */ 4:   5: #include < ...

随机推荐

  1. Linux速成(一)

    全部转载自http://www.runoob.com/linux/linux-intro.html 一.Linux 简介 Linux是一套免费使用和自由传播的类Unix操作系统,是一个基于POSIX和 ...

  2. Received non-all-whitespace CHARACTERS or CDATA event in nextTag(). ,无法整齐打印验证错误。 解析XML文档出现的问题

    在启动keyCloak,想要在standAlone模式下切换数据库,修改standAlone.xml文件时. 在bin/目录下启动standAlone模式出现错误: 10:07:24,799 INFO ...

  3. Netty源码分析第1章(Netty启动流程)---->第4节: 注册多路复用

    Netty源码分析第一章:Netty启动流程   第四节:注册多路复用 回顾下以上的小节, 我们知道了channel的的创建和初始化过程, 那么channel是如何注册到selector中的呢?我们继 ...

  4. SMR解析

    SMR描述 SMR(Shingled Magnetic Recording)叠瓦式磁记录盘是一种采用新型磁存储技术的高容量磁盘.SMR盘将盘片上的数据磁道部分重叠,就像屋顶上的瓦片一样,这种技术被称为 ...

  5. jQuery的基本使用

    一.jQuery简介 jQuery是一个快速.简洁的JavaScript框架,它封装了JavaScript常用的功能代码,提供一种简便的JavaScript设计模式,优化HTML文档操作.事件处理.动 ...

  6. NDK 链接第三方静态库的方法

    将NDK编译的第三方静态拷贝到JNI目录下,在Android.mk中添加如下代码 以openssl静态库(libcrypto-static.a)为例 第一种链接方法:LOCAL_LDFLAGS := ...

  7. iOS中使用RNCryptor对资源文件加密(先加密后拖进项目中)

    概述:IPA 在发布时,业务相关的敏感资源文件以明文的形式存储,由于没有加密保护,这些文件在应用发布后 可能被其他人获取,并结合其他漏洞和手段产生真实攻击.所以我们要 1.在设计.开发阶段,集合业务确 ...

  8. JavaWeb项目通过调用cmd实现备份数据库的功能

    1.别急着上车,先测试一下能否成功调用cmd,可以尝试通过cmd命令打开计算器,代码如下:     2.能成功打开计算器后,证明调用cmd的方法是没错的,现在把cmd命令字符串改成我们备份数据库的 命 ...

  9. TeamWork#3,Week5,The First Meeting of Our Team

    sixsix第一次会议记录 [会议时间]2014年10月23日星期四19:00-20:00 [会议形式]小组讨论 [会议地点]5号公寓 [会议主持]高雅智 [会议记录]张志浩 会议整体流程 一.签到 ...

  10. Hibernate的使用技巧②

    1.Hibernate统计记录的数量 Criteria c = session.createCriteria(User.class.getName());        c.setProjection ...