题目http://acm.hdu.edu.cn/showproblem.php?pid=5692

题目说每个点至多经过一次,那么就是只能一条路线走到底的意思,看到这题的格式,

多个询问多个更新,

自然而然的就会想到线段树或者树状数组,在建树前先做处理,

用DFS将从起点0出发到任一点的距离求出,

然后将这些节点按照一条一条完整的路线的顺序建到树中,

比如样例是1---2---3

|

6 ---4----5

所以建树的其中一种顺序是1 4 5 6 2 3 。当查询的时候的区间应该是从现在这个点开始到这条路线上的终点,更新的时候也是这个区间更新,相当于把这个区间的所有数都加上一个数,与 poj 3468 类似,lazy操作。

 #include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std; typedef long long ll;
const int M = 1e5 + ;
int head[M],cas,num[M],ans,st[M],ed[M];
ll sum[M],a[M]; ll max(ll x,ll y) {return x>y?x:y;} struct Edge{
int to;
int next;
}edge[M*]; void add(int x,int y)
{
edge[cas].to=x;
edge[cas].next=head[y];
head[y]=cas++;
} void dfs(int x,int y)
{
st[x]=++ans;num[ans]=x;
sum[x]+=sum[y];
for (int i=head[x] ; i!=- ; i=edge[i].next)
{
int v=edge[i].to;
if (v==y) continue;
dfs(v,x);
}
ed[x]=ans;
}
struct Tree{
int l,r;
ll ans,mark;
}tree[M*]; void down(int i)
{
if(tree[i].mark)
{
tree[i*].mark+=tree[i].mark;tree[i*+].mark+=tree[i].mark;
tree[i*].ans+=tree[i].mark;tree[i*+].ans+=tree[i].mark;
tree[i].mark=;
}
} void build(int i,int left,int right)
{
tree[i].l=left;tree[i].r=right;
tree[i].mark=;
if (left==right){tree[i].ans=sum[num[left]];return ;}
int mid=(left+right)/;
build(i*,left,mid);
build(i*+,mid+,right);
tree[i].ans=max(tree[i*].ans,tree[i*+].ans);
} ll findest(int i,int left,int right)
{
if(tree[i].l>=left&&tree[i].r<=right)
return tree[i].ans;
down(i);
int mid=(tree[i].l+tree[i].r)/;
if(mid>=right){return findest(i*,left,right);}
else if(mid<left){return findest(i*+,left,right);}
else{return max(findest(i*,left,mid),findest(i*+,mid+,right));} }
void update(int i,int left,int right,ll pos)
{
if(tree[i].l>=left&&tree[i].r<=right){tree[i].mark+=pos;tree[i].ans+=pos;return;}
int mid=(tree[i].l+tree[i].r)/;
down(i);
if(mid<left) update(i*+,left,right,pos);
else if(mid>=right) update(i*,left,right,pos);
else
{
update(i*,left,mid,pos);
update(i*+,mid+,right,pos);
}
tree[i].ans=max(tree[i*].ans,tree[i*+].ans);
} int main()
{
int t,n,m,e=;
scanf("%d",&t);
while (t--)
{
printf("Case #%d:\n",++e);
scanf("%d%d",&n,&m);
memset(head,-,sizeof(head));
for (int i= ; i<n ; i++){
int a,b;
scanf("%d%d",&a,&b);
a++,b++;
add(a,b);add(b,a);
}
cas=;ans=;
for (int i= ; i<=n ; i++) scanf("%I64d",&a[i]),sum[i]=a[i];
dfs(,);
build(,,n);
while (m--)
{
int w,b;ll c;
scanf("%d",&w);
if (w){
scanf("%d",&b);b++;
printf("%I64d\n",findest(,st[b],ed[b]));
}
else{
scanf("%d%I64d",&b,&c);b++;
ll q=c-a[b];
a[b]=c;
update(,st[b],ed[b],q);
}
}
}
return ;
}

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

  1. HDU 5877 dfs+ 线段树(或+树状树组)

    1.HDU 5877  Weak Pair 2.总结:有多种做法,这里写了dfs+线段树(或+树状树组),还可用主席树或平衡树,但还不会这两个 3.思路:利用dfs遍历子节点,同时对于每个子节点au, ...

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

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

  3. hdu 4031 attack 线段树区间更新

    Attack Time Limit: 5000/3000 MS (Java/Others)    Memory Limit: 65768/65768 K (Java/Others)Total Subm ...

  4. hdu 4288 离线线段树+间隔求和

    Coder Time Limit: 20000/10000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Su ...

  5. hdu 3016 dp+线段树

    Man Down Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total S ...

  6. Codeforces1110F Nearest Leaf dfs + 线段树 + 询问离线

    Codeforces1110F dfs + 线段树 + 询问离线 F. Nearest Leaf Description: Let's define the Eulerian traversal of ...

  7. dfs+线段树 zhrt的数据结构课

    zhrt的数据结构课 这个题目我觉得是一个有一点点思维的dfs+线段树 虽然说看起来可以用树链剖分写,但是这个题目时间卡了树剖 因为之前用树剖一直在写这个,所以一直想的是区间更新,想dfs+线段树,有 ...

  8. hdu 5692(dfs序+线段树,好题)

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

  9. HDU 3974 Assign the task (DFS+线段树)

    题意:给定一棵树的公司职员管理图,有两种操作, 第一种是 T x y,把 x 及员工都变成 y, 第二种是 C x 询问 x 当前的数. 析:先把该树用dfs遍历,形成一个序列,然后再用线段树进行维护 ...

随机推荐

  1. java中Integer和int的区别(转)

    int和Integer的区别 1.Integer是int的包装类,int则是java的一种基本数据类型 2.Integer变量必须实例化后才能使用,而int变量不需要 3.Integer实际是对象的引 ...

  2. python使用cv2显示图片像素值

    给定一张灰度图,显示这张图片的像素值 def show_image_pixel(img): ''' :param img: 需要输出像素值的图像,要求是灰度图 :return: 无返回值 ''' he ...

  3. php首字母 大写 数组去重复

    $zimu[]=strtoupper(substr( $value['title'], 0, 1 ));//大写 $zimu[]=strtolower(substr( $value['title'], ...

  4. Java的学习01

    记录每天的学习情况.加油. /** * 测试包装类 * @author 小白 * */ public class TestWrappedClass { public static void main( ...

  5. 04_web基础(八)之车票实现增删改查初级版本

    43.web页面显示车票列表简略完成 代码: 控制层代码 package com.day03.station.controller; import com.day03.station.model.Ti ...

  6. 解题(StringJiaMi--字符串加密)

    题目描述 有一种技巧可以对数据进行加密,它使用一个单词作为它的密匙.下面是它的工作原理:首先,选择一个单词作为密匙,如TRAILBLAZERS.如果单词中包含有重复的字母,只保留第1个,其余几个丢弃. ...

  7. jQuery 替换元素

    参考https://www.cnblogs.com/halai/p/6868027.html http://www.w3school.com.cn/jquery/manipulation_replac ...

  8. centos 7 redis-4.0.11 哨兵

    redis-master:192.168.199.223 redis-slave_1: 192.168.199.224 redis-slave_2: 192.168.199.252 redis-mas ...

  9. Mac IntelliJ IDEA 2017(java开发集成环境)附注册码和破解教程 v2017.3.5破解版

    原文:http://www.orsoon.com/Mac/155938.html 原文中含有软件下载地址 软件介绍 IntelliJ IDEA 2017 Mac激活版是Mac平台上的一款java开发集 ...

  10. python数据分析之matplotlib学习

    本文作为学习过程中对matplotlib一些常用知识点的整理,方便查找. 类MATLAB API 最简单的入门是从类 MATLAB API 开始,它被设计成兼容 MATLAB 绘图函数. from p ...