Snacks

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

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

思路:用Hash[lch[u]]记录从根节点带u结点所经过结点的权值之和。那么从根节点经过u结点所有路径权值之和的最大值为 max(Hash[lch[u]],..,Hash[rch[u]]);

#pragma comment(linker,"/STACK:1024000000,1024000000")
#include <cstdio>
#include <vector>
#include <cstring>
#include <algorithm>
using namespace std;
const int MAXN=;
typedef long long LL;
int n,m;
vector<int> arc[MAXN];
int val[MAXN]; int lch[MAXN],rch[MAXN],key;
LL has[MAXN];
void dfs(int u,int fa)
{
lch[u]=++key;
has[lch[u]]=val[u]+has[lch[fa]];
for(int i=;i<arc[u].size();i++)
{
int to=arc[u][i];
if(to!=fa)
{
dfs(to,u);
}
}
rch[u]=key;
} struct Node{
int l,r;
LL mx,lazy;
}segTree[MAXN*];
void build(int rt,int l,int r)
{
segTree[rt].l=l;
segTree[rt].r=r;
segTree[rt].lazy=;
if(l==r)
{
segTree[rt].mx=has[l];
return ;
}
int mid=(l+r)>>;
build(rt<<,l,mid);
build((rt<<)|,mid+,r);
segTree[rt].mx=max(segTree[rt<<].mx,segTree[(rt<<)|].mx);
} void pushDown(int rt)
{
if(segTree[rt].lazy!=)
{
segTree[rt<<].mx+=segTree[rt].lazy;
segTree[(rt<<)|].mx+=segTree[rt].lazy;
segTree[rt<<].lazy+=segTree[rt].lazy;
segTree[(rt<<)|].lazy+=segTree[rt].lazy;
segTree[rt].lazy=;
}
} void update(int rt,int l,int r,LL value)
{
if(segTree[rt].l==l&&segTree[rt].r==r)
{
segTree[rt].mx+=value;
segTree[rt].lazy+=value;
return ;
}
pushDown(rt);
int mid=(segTree[rt].l+segTree[rt].r)>>;
if(r<=mid)
{
update(rt<<,l,r,value);
}
else if(mid<l)
{
update((rt<<)|,l,r,value);
}
else
{
update(rt<<,l,mid,value);
update((rt<<)|,mid+,r,value);
}
segTree[rt].mx=max(segTree[rt<<].mx,segTree[(rt<<)|].mx);
} LL query(int rt,int l,int r)
{
if(segTree[rt].l==l&&segTree[rt].r==r)
{
return segTree[rt].mx;
}
pushDown(rt);
int mid=(segTree[rt].l+segTree[rt].r)>>;
if(r<=mid)
{
return query(rt<<,l,r);
}
else if(mid<l)
{
return query((rt<<)|,l,r);
}
else
{
return max(query(rt<<,l,mid),query((rt<<)|,mid+,r));
}
segTree[rt].mx=max(segTree[rt<<].mx,segTree[(rt<<)|].mx);
}
int main()
{
int T;
scanf("%d",&T);
for(int cas=;cas<=T;cas++)
{
key=;
memset(has,,sizeof(has));
scanf("%d%d",&n,&m);
for(int i=;i<=n;i++) arc[i].clear();
for(int i=;i<n-;i++)
{
int u,v;
scanf("%d%d",&u,&v);
u++;v++;
arc[u].push_back(v);
arc[v].push_back(u);
}
for(int i=;i<=n;i++)
{
scanf("%d",&val[i]);
}
dfs(,);
build(,,n);
printf("Case #%d:\n",cas);
while(m--)
{
int type;
scanf("%d",&type);
if(type==)
{
int x;
scanf("%d",&x);
x++;
LL res=query(,lch[x],rch[x]);
printf("%lld\n",res);
}
else
{
int x,y;
scanf("%d %d",&x,&y);
x++;
update(,lch[x],rch[x],y-val[x]);
val[x]=y;//注意更新
}
}
}
return ;
}

HDU5692(dfs序+线段树)的更多相关文章

  1. hdu5692 dfs序线段树

    这是补的知识点,按先序遍历的顺序建立dfs序,用左右两个值代表整个区间,因为dfs序最重要的特点就是子树的区间是连续的 建立线段树时,需要用重新标过的 下标来建立 #pragma comment(li ...

  2. Educational Codeforces Round 6 E dfs序+线段树

    题意:给出一颗有根树的构造和一开始每个点的颜色 有两种操作 1 : 给定点的子树群体涂色 2 : 求给定点的子树中有多少种颜色 比较容易想到dfs序+线段树去做 dfs序是很久以前看的bilibili ...

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

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

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

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

  5. BZOJ2434 [Noi2011]阿狸的打字机(AC自动机 + fail树 + DFS序 + 线段树)

    题目这么说的: 阿狸喜欢收藏各种稀奇古怪的东西,最近他淘到一台老式的打字机.打字机上只有28个按键,分别印有26个小写英文字母和'B'.'P'两个字母.经阿狸研究发现,这个打字机是这样工作的: 输入小 ...

  6. POJ 3321 DFS序+线段树

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

  7. 【XSY2667】摧毁图状树 贪心 堆 DFS序 线段树

    题目大意 给你一棵有根树,有\(n\)个点.还有一个参数\(k\).你每次要删除一条长度为\(k\)(\(k\)个点)的祖先-后代链,问你最少几次删完.现在有\(q\)个询问,每次给你一个\(k\), ...

  8. F - Change FZU - 2277 (DFS序+线段树)

    题目链接: F - Change FZU - 2277 题目大意: 题意: 给定一棵根为1, n个结点的树. 有q个操作,有两种不同的操作 (1) 1 v k x : a[v] += x, a[v ' ...

  9. BZOJ4551[Tjoi2016&Heoi2016]树——dfs序+线段树/树链剖分+线段树

    题目描述 在2016年,佳媛姐姐刚刚学习了树,非常开心.现在他想解决这样一个问题:给定一颗有根树(根为1),有以下 两种操作:1. 标记操作:对某个结点打上标记(在最开始,只有结点1有标记,其他结点均 ...

随机推荐

  1. 文件系统的特性,linux的EXT2文件系统【转】

    本文转载自:https://blog.csdn.net/tongyijia/article/details/52809281 先来提出三个概念: - superblock - inode - bloc ...

  2. 【bzoj3238】差异[AHOI2013](后缀数组+单调栈)

    题目传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=3238 这道题从大概半年以前就开始啃了,不过当时因为一些细节没调出来,看了Sakits神犇 ...

  3. springboot---aop切片编程

    1.介绍 面向切面编程,关注点代码与业务代码分离,就是给指定方法执行前执行后..插入重复代码 关注点:重复代码 切面:被切面的类 切入点:执行目标对象方法,动态植入切片代码 2.部署步骤 2.1:添加 ...

  4. UvaLive 5811 概率DP

    题意 : 有54张牌 问抽多少张牌能使每种花色都至少是给定的数字 两张王牌可以被选择为任何花色 高放学长真是太腻害辣! 设置dp[][][][][x][y] 前四维代表四种真的花色的数量 后两维xy代 ...

  5. YII2笔记之三

    activeform布局findAll等不能满足where, order by, limit,底层调用了findByConditioncol-md col-lg的使用 view的方法,前三个常用ren ...

  6. Python-flask中数据库连接池DBUtils

    一.DBUtils DBUtils是Python的一个用于实现数据库连接池的模块. 连接池的三种模式: 第一种模式:             它的缺点:每一次请求反复创建数据库的链接,链接的次数太多 ...

  7. Android 6.0运行时权限第三方库的使用-----RxPermissions

    运行时权限的讲解在前一篇博客已经算是说的比较清楚了,这里就不说了,如果对6.0这个新特性不是很了解的朋友建议先看看(地址:http://blog.csdn.net/qq_33923079/articl ...

  8. review05

    子类与继承 所有类都是Object的子孙类. 子类继承了父类的成员变量和方法,就好像是在子类中直接定义了一样. 如果子类和父类在同一个包中,子类自然地继承了父类中不是private的成员变量和方法. ...

  9. 网页seo

    两大 网站布局和代码编辑 网站结构布局优化 1.控制首页链接数量 100以内2.偏平化的目录层次 百度蜘蛛点三次 超过三次,找不到结果. 导航SEO优化导航最好是文字 图片最好都加上 title 和a ...

  10. php 策略模式案例

    策略模式,将一组特定的行为和算法封装成类,以适应某些特定的上下文环境. eg:假如有一个电商网站系统,针对男性女性用户要各自跳转到不同的商品类目,并且所有的广告位展示不同的广告.在传统的代码中,都是在 ...