hdu 5692(dfs+线段树) Snacks
题目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的更多相关文章
- HDU 5877 dfs+ 线段树(或+树状树组)
1.HDU 5877 Weak Pair 2.总结:有多种做法,这里写了dfs+线段树(或+树状树组),还可用主席树或平衡树,但还不会这两个 3.思路:利用dfs遍历子节点,同时对于每个子节点au, ...
- Snacks HDU 5692 dfs序列+线段树
Snacks HDU 5692 dfs序列+线段树 题意 百度科技园内有n个零食机,零食机之间通过n−1条路相互连通.每个零食机都有一个值v,表示为小度熊提供零食的价值. 由于零食被频繁的消耗和补充, ...
- hdu 4031 attack 线段树区间更新
Attack Time Limit: 5000/3000 MS (Java/Others) Memory Limit: 65768/65768 K (Java/Others)Total Subm ...
- hdu 4288 离线线段树+间隔求和
Coder Time Limit: 20000/10000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Su ...
- hdu 3016 dp+线段树
Man Down Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total S ...
- Codeforces1110F Nearest Leaf dfs + 线段树 + 询问离线
Codeforces1110F dfs + 线段树 + 询问离线 F. Nearest Leaf Description: Let's define the Eulerian traversal of ...
- dfs+线段树 zhrt的数据结构课
zhrt的数据结构课 这个题目我觉得是一个有一点点思维的dfs+线段树 虽然说看起来可以用树链剖分写,但是这个题目时间卡了树剖 因为之前用树剖一直在写这个,所以一直想的是区间更新,想dfs+线段树,有 ...
- hdu 5692(dfs序+线段树,好题)
Snacks Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Total Sub ...
- HDU 3974 Assign the task (DFS+线段树)
题意:给定一棵树的公司职员管理图,有两种操作, 第一种是 T x y,把 x 及员工都变成 y, 第二种是 C x 询问 x 当前的数. 析:先把该树用dfs遍历,形成一个序列,然后再用线段树进行维护 ...
随机推荐
- Java学习04 (第一遍)
封装.抽象.继承和多态.封装:在面向对象语言中,封装特性是由类来体现的,我们将现实生活中的一类实体定义成类,其中包括属性和行为(在Java中就是方法),就好像人类,可以具有name,sex,age等属 ...
- 拓扑排序-有向无环图(DAG, Directed Acyclic Graph)
条件: 1.每个顶点出现且只出现一次. 2.若存在一条从顶点 A 到顶点 B 的路径,那么在序列中顶点 A 出现在顶点 B 的前面. 有向无环图(DAG)才有拓扑排序,非DAG图没有拓扑排序一说. 一 ...
- js基础-对象
对象是一组属性方法的无序集 除了字符串.数值类型.布尔类型.null.undefined 之外的其他都是对象类型 对象都是引用类型 Object类型对象.数组类型对象 如果一个普通函数前面加了new ...
- kotlin函数api
原 Kotlin学习(4)Lambda 2017年09月26日 21:00:03 gwt0425 阅读数:551 记住Lambda的本质,还是一个对象.和JS,Python等不同的是,Kotlin ...
- 什么是JIT,写的很好
什么是JIT 一些其他解释的网站:http://www.sohu.com/a/169704040_464084 1.动态编译(dynamic compilation)指的是“在运行时进行编译”:与之相 ...
- apache安装配置
因为个人是在docker上面做实验的,所以可以多少会有些出入. 1.先启动一个docker,配置好基本的工具,网络啊,ssh啊是,tar啊,wget啊,vim等等. 其次去官网获取自己想要的压缩文件的 ...
- js实现多级复选框的交互
功能介绍 整个复选框是包含多级,可能有父级,可能有子级,在勾选复选框时,要做两种判断: 1要判断它下面有没有子级,有子级将子级的选中状态checked变得和自己一样. 2要判断它是否有父级,有父级 ...
- java面试题:基础知识
类和对象 Q:讲一下面向对象OOP思想. 面向对象主要是抽象,封装,继承,多态. 多态又分为重载和重写.重载主要是方法参数类型不一样,重写则是方法内容不一样. Q:抽象类和接口有什么区别? 抽象类中可 ...
- WAS 默认端口列表
- MongoDB之Array Object的特殊操作
相比关系型数据库,Array[1,2,3,4,5]和Object{'name':'Wjs'}是MongoDB比较特殊的类型 db.Wjs.insert({"name":" ...