题目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. jenkins 自动触发

    在gitlab上配置连接jenkins ,将Jenkins的Secret token 与Build URL 复制到gitlab中 在settings标签下面,找到OutBound Request,勾选 ...

  2. js对数组对象的操作以及方法的使用

    js对数组对象的操作以及方法的使用 如何声明创建一个数组对象: var arr = new Array(); 或者 var arr = []; 如何移除所有数组中数据? arrayJson.dataL ...

  3. workerman channel组件集群推送

    <?phpuse Workerman\Worker; require_once '../../web/Workerman/Autoloader.php';require_once '../../ ...

  4. get请求中url传参中文乱码问题--集锦

    一:get请求url中带有中文参数,有三种方式进行处理防止中文乱码 1.如果使用tomcat作为服务器,那么修改tomcat配置文件conf/server.xml中,在  <Connector  ...

  5. room 二分图最大匹配KM

    #include<bits/stdc++.h> #define fi first #define se second #define INF 0x3f3f3f3f #define fio ...

  6. AdminLTE 侧边栏收缩时触发的事件

    点击此处,会触发 expanded.pushMenu 或 collapsed.pushMenu 事件 如果需要在事件触发时编写相关逻辑,可用如下方式 $("body").on(&q ...

  7. centos7 搭建keepalived+Nginx+tomcat

    准备1台 192.168.2.224  安装Nginx,2台安装tomcat   192.168.2.222   192.168.2.223 1.安装Nginx: 上传pcre-8.36.tar.gz ...

  8. elasticsearch 不同集群数据同步

    采用快照方式 1.源集群采用NFS,注意权限 2.共享目录完成后,在所有ES服务器上挂载为同一目录 3.创建快照仓库 put _snapshot/my_backup{ "type" ...

  9. webpack 打包问题2

  10. ASCII码翻译方法可直接使用谷歌

    ASCII码翻译方法可直接使用谷歌. 如: key{you are right} 将此段ASCII码输入谷歌搜索栏,直接翻译结果: