HDU 5692 Snacks
题目链接【http://acm.hdu.edu.cn/showproblem.php?pid=5692】
题意:一棵树,每个节点有权值,有两种操作:1、修改某个点的权值,2、求以x根的子树中的节点到根的权值和的最大值。
题解:DFS序:对点进行重新编号,每个子树中的所有的节点的编号是连续的。映射到线段树上,进行区间修改,区间查询。
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
typedef long long LL;
const int maxn = 1e6 + ;
int T, N, Q;
LL a[maxn], sum[maxn];
struct Edge
{
int to, next;
Edge (int to = , int next = ): to(to), next(next) {}
} E[maxn * ];
int head[maxn], tot;
void initEdge()
{
for(int i = ; i <= N + ; i++) head[i] = -;
tot = ;
}
void addEdge(int u, int v)
{
E[tot] = Edge(v, head[u]);
head[u] = tot++;
}
int L[maxn], R[maxn], dfs_clock;
void DFS(int u, int fa)
{
L[u] = ++dfs_clock;
sum[L[u]] = a[u] + sum[L[fa]];
for(int k = head[u]; ~k; k = E[k].next)
{
int v = E[k].to;
if(v == fa) continue;
DFS(v, u);
}
R[u] = dfs_clock;
}
LL ma[maxn * ], fg[maxn * ];
void Build(int id, int L, int R)
{
fg[id] = ;
if(L == R)
{
ma[id] = sum[L];
return ;
}
int mid = (L + R) >> ;
Build(id << , L, mid);
Build(id << | , mid + , R);
ma[id] = max(ma[id << ], ma[id << | ]);
}
inline void push_down(int id)
{
if(fg[id])
{
fg[id << ] += fg[id];
ma[id << ] += fg[id];
fg[id << | ] += fg[id];
ma[id << | ] += fg[id];
fg[id] = ;
}
}
void update(int id, int L, int R, int l, int r, LL val)
{
if(L == l && R == r)
{
fg[id] += val;
ma[id] += val;
return ;
}
push_down(id);
int mid = (L + R) >> ;
if(r <= mid)
update(id << , L, mid, l, r, val);
else if(l >= mid + )
update(id << | , mid + , R, l, r, val);
else
{
update(id << , L, mid, l, mid, val);
update(id << | , mid + , R, mid + , r, val);
}
ma[id] = max(ma[id << ], ma[id << | ]);
}
LL query(int id, int L, int R, int l, int r)
{
if(L == l && R == r)
return ma[id];
push_down(id);
int mid = (L + R) >> ;
if(r <= mid)
return query(id << , L, mid, l, r);
else if(l >= mid + )
return query(id << | , mid + , R, l, r);
else
{
LL t = query(id << , L, mid, l, mid);
return max(t, query(id << | , mid + , R, mid + , r));
}
}
int main ()
{
int ic = ;
scanf("%d", &T);
while(T--)
{
scanf("%d %d", &N, &Q);
initEdge();
for(int i = ; i <= N - ; i++)
{
int u, v;
scanf("%d %d", &u, &v);
addEdge(u + , v + );
addEdge(v + , u + );
}
for(int i = ; i <= N; i++) scanf("%lld", &a[i]);
dfs_clock = , DFS(, );
Build(, , N);
printf("Case #%d:\n", ++ic);
for(int i = ; i <= Q; i++)
{
int ty, x;
LL y;
scanf("%d", &ty);
if(ty == )
{
scanf("%d %lld", &x, &y);
x++;
update(, , N, L[x], R[x], y - a[x]);
a[x] = y;
}
else if(ty == )
{
scanf("%d", &x);
x++;
LL ans = query(, , N, L[x], R[x]);
printf("%lld\n", ans);
}
}
}
return ;
}
HDU 5692 Snacks的更多相关文章
- HDU.5692 Snacks ( DFS序 线段树维护最大值 )
HDU.5692 Snacks ( DFS序 线段树维护最大值 ) 题意分析 给出一颗树,节点标号为0-n,每个节点有一定权值,并且规定0号为根节点.有两种操作:操作一为询问,给出一个节点x,求从0号 ...
- HDU 5692 Snacks bfs版本dfs序 线段树
Snacks 题目连接: http://acm.hdu.edu.cn/showproblem.php?pid=5692 Description 百度科技园内有n个零食机,零食机之间通过n−1条路相互连 ...
- 【DFS序+线段树区间更新区间求最值】HDU 5692 Snacks
http://acm.hdu.edu.cn/showproblem.php?pid=5692 [思路] 每更新一个点,子树的所有结点都要更新,所以是区间更新 每查询一个点,子树的所有结点都要查询,所以 ...
- hdu 5692 Snacks 线段树+dfs
Snacks Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Total Sub ...
- hdu 5692 Snacks(dfs时间戳+线段树)
Snacks Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Total Sub ...
- HDU 5692 Snacks(DFS序+线段树)
Snacks Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Total Sub ...
- Snacks HDU 5692 dfs序列+线段树
Snacks HDU 5692 dfs序列+线段树 题意 百度科技园内有n个零食机,零食机之间通过n−1条路相互连通.每个零食机都有一个值v,表示为小度熊提供零食的价值. 由于零食被频繁的消耗和补充, ...
- hdu 5692(dfs+线段树) Snacks
题目http://acm.hdu.edu.cn/showproblem.php?pid=5692 题目说每个点至多经过一次,那么就是只能一条路线走到底的意思,看到这题的格式, 多个询问多个更新, 自然 ...
- HDU 5692 线段树+dfs序
Snacks Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Total Sub ...
随机推荐
- 分享一个数据库sql_mode 引起的坑
sql_mode坑 MySQL 5.7.x 默认值: ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR ...
- JavaScript arguments你不知道的秘密
(function test(x){ x=10; console.log(arguments[0], x); //undefined, 10 })(); (function test(x){ x=10 ...
- [linux]安装code::blocks
1.安装基本编译环境 $sudo apt-get install build-essential $sudo apt-get install gdb 2.安装codeblock $sudo apt-g ...
- 【洛谷】3375 KMP字符串匹配
[算法]KMP [题解][算法]字符串 #include<cstdio> #include<algorithm> #include<cstring> using n ...
- 【LibreOJ】#6298. 「CodePlus 2018 3 月赛」华尔兹 BFS
[题意]给定n*m的网格,起点和终点位置,一些格指定下一步的方向,一些格任意.要求为方向任意的格确定方向,使起点可以走到终点.n,m<=50. [算法]BFS [题解]这道题最好用BFS,因为D ...
- 【CodeForces】915 F. Imbalance Value of a Tree 并查集
[题目]F. Imbalance Value of a Tree [题意]给定n个点的带点权树,求所有路径极差的和.n,ai<=10^6 [算法]并查集 [题解]先计算最大值的和,按点权从小到大 ...
- SVM支持向量机的基本原理
SVM支持向量机的基本原理 对于很多分类问题,例如最简单的,一个平面上的两类不同的点,如何将它用一条直线分开?在平面上我们可能无法实现,但是如果通过某种映射,将这些点映射到其它空间(比如说球面上等), ...
- okhttp3使用详解
http://blog.csdn.net/itachi85/article/details/51190687
- 【nginx+tomcat集群】Nginx1.12.2+Tomcat7集群+负载均衡+Session共享
今天想着将项目优化一下,就想的实现集群分布,在本机测试:利用nginx+tomcat实现 通过上一篇博客(http://www.cnblogs.com/qlqwjy/p/8535235.html),N ...
- redis基础之redis-sentinel(哨兵集群)(六)
前言 redis简单的主从复制在生产的环境下可能是不行的,因为从服务器只能读不能写,如果主服务器挂掉,那么整个缓存系统不能写入了:redis自带了sentinel(哨兵)机制可以实现高可用. redi ...