Snacks

Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 2165    Accepted Submission(s): 513

Problem Description
百度科技园内有n个零食机,零食机之间通过n−1条路相互连通。每个零食机都有一个值v,表示为小度熊提供零食的价值。

由于零食被频繁的消耗和补充,零食机的价值v会时常发生变化。小度熊只能从编号为0的零食机出发,并且每个零食机至多经过一次。另外,小度熊会对某个零食机的零食有所偏爱,要求路线上必须有那个零食机。

为小度熊规划一个路线,使得路线上的价值总和最大。

 
Input
输入数据第一行是一个整数T(T≤10),表示有T组测试数据。

对于每组数据,包含两个整数n,m(1≤n,m≤100000),表示有n个零食机,m次操作。

接下来n−1行,每行两个整数x和y(0≤x,y<n),表示编号为x的零食机与编号为y的零食机相连。

接下来一行由n个数组成,表示从编号为0到编号为n−1的零食机的初始价值v(|v|<100000)。

接下来m行,有两种操作:0 x y,表示编号为x的零食机的价值变为y;1 x,表示询问从编号为0的零食机出发,必须经过编号为x零食机的路线中,价值总和的最大值。

本题可能栈溢出,辛苦同学们提交语言选择c++,并在代码的第一行加上:

`#pragma comment(linker, "/STACK:1024000000,1024000000") `

 
Output
对于每组数据,首先输出一行”Case #?:”,在问号处应填入当前数据的组数,组数从1开始计算。

对于每次询问,输出从编号为0的零食机出发,必须经过编号为x零食机的路线中,价值总和的最大值。

 
Sample Input
1
6 5
0 1
1 2
0 3
3 4
5 3
7 -5 100 20 -5 -7
1 1
1 3
0 2 -1
1 1
1 5
 
Sample Output
Case #1:
102
27
2
20
 

 
 
这题是把树化为线性去处理的典型题。
对于本题我们要求的是经过从根并经过点s的路径最大权值,即到达该点和该点子树上每个节点的路径总权值里的最大值。这个可以用前缀和求出到每个点的总权值。并且这之中带有权值修改,一下就令人想到线段树。但线段树维护的是一个区间上的值,那怎么把一颗树化为线性呢?那么此时dfs时间戳就派上用场了。我们需要把一棵树用dfs时间戳将这棵树化为一个线性的区间,区间每个点存的是dfs时间戳里的节点所对应的从0根节点到该节点的路径总权值。此时我们要求解点s的从根并经过点s的路径最大权值,就变成了求解pre[s]~last[s]这个区间里所有权值的最大值,而修改某个点u的权值相当于更新pre[u]~last[u]里的所有权值。于是该题就能用线段树维护求解了。
 #pragma comment(linker, "/STACK:1024000000,1024000000")
#include<cstdio>
#include<iostream>
#include<cstring>
#define clr(x) memset(x,0,sizeof(x))
#define clr_1(x) memset(x,-1,sizeof(x))
#define LL long long
#define INF (1e18)
using namespace std;
struct edg
{
int next,to;
}edge[<<];
struct seg
{
int l,r;
LL maxn,tag;
}segt[<<];
int head[],dfstm[],pre[],last[],n,m,k,u,v,s,T,cnt;
LL value[],sum[],x;
LL max(LL a, LL b)
{
return a>b?a:b;
}
void addedge(int u,int v)
{
edge[++cnt].to=v;
edge[cnt].next=head[u];
head[u]=cnt;
return ;
}
void dfs(int i,int fa)
{
sum[i]=sum[fa]+value[i];
dfstm[++k]=i;
pre[i]=k;
for(int j=head[i];j!=-;j=edge[j].next)
if(edge[j].to!=fa)
dfs(edge[j].to,i);
last[i]=k;
return ;
}
void init(int i,int l,int r)
{
segt[i]=(seg){l,r,,};
if(l==r)
{
segt[i].maxn=sum[dfstm[l]];
return;
}
int mid=(l+r)>>;
init(i<<,l,mid);
init(i<<|,mid+,r);
segt[i].maxn=max(segt[i<<].maxn,segt[i<<|].maxn);
return ;
}
void pushdown(int i)
{
if(segt[i].tag!=)
{
if(segt[i].l!=segt[i].r)
{
segt[i<<].maxn+=segt[i].tag;
segt[i<<|].maxn+=segt[i].tag;
segt[i<<].tag+=segt[i].tag;
segt[i<<|].tag+=segt[i].tag;
}
segt[i].tag=;
}
return ;
}
void update(int i,int l,int r,LL addval)
{
if(segt[i].l>=l && segt[i].r<=r)
{
segt[i].tag+=addval;
segt[i].maxn+=addval;
return ;
}
pushdown(i);
int mid=(segt[i].l+segt[i].r)>>;
if(mid>=r)
{
update(i<<,l,r,addval);
}
else if(mid<l)
{
update(i<<|,l,r,addval);
}
else
{
update(i<<,l,r,addval);
update(i<<|,l,r,addval);
}
segt[i].maxn=max(segt[i<<].maxn,segt[i<<|].maxn);
return ;
}
LL query(int i,int l,int r)
{
if(segt[i].l>=l && segt[i].r<=r)
{
return segt[i].maxn;
}
pushdown(i);
int mid=(segt[i].l+segt[i].r)>>;
LL ans=-INF;
if(mid>=r)
{
ans=max(ans,query(i<<,l,r));
}
else if(mid<l)
{
ans=max(ans,query(i<<|,l,r));
}
else
{
ans=max(ans,query(i<<,l,r));
ans=max(ans,query(i<<|,l,r));
}
segt[i].maxn=max(segt[i<<].maxn,segt[i<<|].maxn);
return ans;
}
int main()
{
scanf("%d",&T);
for(int kase=;kase<=T;kase++)
{
clr_1(head);
clr(sum);
cnt=;
k=;
printf("Case #%d:\n",kase);
scanf("%d%d",&n,&m);
for(int i=;i<n;i++)
{
scanf("%d%d",&u,&v);
addedge(u,v);
addedge(v,u);
}
for(int i=;i<n;i++)
{
scanf("%lld",&value[i]);
}
dfs(,);
init(,,n);
for(int i=;i<=m;i++)
{
scanf("%d",&k);
if(k)
{
scanf("%d",&u);
printf("%lld\n",query(,pre[u],last[u]));
}
else
{
scanf("%d%lld",&u,&x);
update(,pre[u],last[u],x-value[u]);
value[u]=x;
}
}
}
return ;
}

hdu 5692 Snacks(dfs时间戳+线段树)的更多相关文章

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

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

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

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

  3. hdu 3974 dfs时间戳+线段树

    题意: 一个公司里面每个员工都有一个顶头上司,一旦给某个员工分配任务后,这个员工以及该员工的所有下属都在做该任务. 有若干操作,分配给员工任务以及查询该员工正在执行的任务. 题解: 典型的更新字树的操 ...

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

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

  5. HDU5692 Snacks DFS序 线段树

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

  6. HDU3974 Assign the task —— dfs时间戳 + 线段树

    题目链接:https://vjudge.net/problem/HDU-3974 There is a company that has N employees(numbered from 1 to ...

  7. HDU - 4366 Successor DFS区间+线段树

    Successor:http://acm.hdu.edu.cn/showproblem.php?pid=4366 参考:https://blog.csdn.net/colin_27/article/d ...

  8. 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 ...

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

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

随机推荐

  1. Sketch VS Photoshop

    参考:http://mp.weixin.qq.com/s?__biz=MjM5NTQ5MjIyMA==&mid=217309554&idx=4&sn=4d6a5239ca813 ...

  2. Angular2.0 基础:双向数据绑定 [(ngModel)]

    在属性绑定中,值从模型到屏幕上的目标属性 (property). 通过把属性名括在方括号中来标记出目标属性,[]. 这是从模型到视图的单向数据绑定. 而在事件绑定中,值是从屏幕上的目标属性 到 mod ...

  3. android 内核调试

    这篇文档给出使用android emulator 和 arm-linux-androideabi-gdb 调试 android kernel 的方法 1. checkout goldfish 源码: ...

  4. 使用 ftrace 调试 Linux 内核【转】

    转自:http://blog.csdn.net/adaptiver/article/details/7930646 使用 ftrace 调试 Linux 内核,第 1 部分 http://blog.c ...

  5. gnu app url[web][5星]

    http://www.gnu.org/software/software.zh-cn.html http://linux.chinaunix.net/news/2010/12/07/1175310.s ...

  6. C++ 流操作符重载函数

    1. 问题 在C++中,在进行输入输出操作时,我们首先会想到用cout, cin这两个库操作语句来实现,比如 cout << 8 << "hello world!&q ...

  7. [How to] 真机调试

    1.简介 真机调试介绍. 在xcode7之前需要每年99刀的代价才能活着开发者权限并能够在真机上调试,现在如果单纯的想在真机上调是就不必花这个钱了. 2.步骤 完毕.

  8. iframe自适应高度的方法

    不带边框的iframe因为能和网页无缝的结合从而不刷新新页面的情况下实现更新页面部分的数据成为可能,可是iframe却不像层那样可以收缩自如,iframe高度需要动态的调整需要JS来配合使用,只能通过 ...

  9. IE6/IE7下:inline-block不兼容的问题

    IE6/IE7下对display:inline-block的支持性不好.    1.inline元素的display属性设置为inline-block时,所有的浏览器都支持:    2.block元素 ...

  10. SPOJ Two Paths

    Description 给定一个无向图,含有一定的路.从中找出两个最长的路径(每条路径有一些相通路组成)这两个路径不能经过公共的点,求何时二路径的乘积最大. 本题给出的无向图是一棵树,每边权值为1. ...