HDU_5692_dfs序+线段树
http://acm.hdu.edu.cn/showproblem.php?pid=5692
这道题真的是看了题解还搞了一天,把每条路径后序遍历按1-n重新标号,储存每个点在哪些路径中出现过(l和r数组),然后转化成线段树来更新和取最大值。
注意,如果使用递归建线段树,数组要开4n才能保证不超。
刚开始更新的函数每一遍更新了所有子树,然后超时了,后来在tree中加了个add,保存子树需要增加的量,如果用到这个子树,在把这个量加起来,简直巧妙。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
#define INF 0x3f3f3f3f
#pragma comment(linker, "/STACK:1024000000,1024000000")
using namespace std; vector<int> line[];
int n,m,cnt,l[],r[];
long long w[],init[];
struct segtree
{
int left,right;
long long maxx,add;
}tree[]; void dfs(int now,int pre,long long sum)
{
sum += w[now];
int flag = ;
l[now] = INF;
for(int i = ;i < line[now].size();i++)
{
int next = line[now][i];
if(next == pre) continue;
flag = ;
dfs(next,now,sum);
l[now] = min(l[now],l[next]);
}
init[cnt] = sum;
r[now] = cnt++;
if(flag) l[now] = r[now];
} void build(int pos,int l,int r)
{
tree[pos].left = l;
tree[pos].right = r;
tree[pos].add = ;
if(l == r) tree[pos].maxx = init[l];
else
{
int mid = (l+r)/;
build(pos*,l,mid);
build(pos*+,mid+,r);
tree[pos].maxx = max(tree[pos*].maxx,tree[pos*+].maxx);
}
} void update(int pos,int l,int r,long long v)
{
if(tree[pos].add != )
{
if(tree[pos].left != tree[pos].right)
{
tree[pos*].maxx += tree[pos].add;
tree[pos*].add += tree[pos].add;
tree[pos*+].maxx += tree[pos].add;
tree[pos*+].add += tree[pos].add;
tree[pos].add = ;
}
}
if(tree[pos].left ==
l && r == tree[pos].right)
{
tree[pos].maxx += v;
tree[pos].add += v;
return;
}
int mid = (tree[pos].left+tree[pos].right)/;
if(r <= mid) update(pos*,l,r,v);
else if(l > mid) update(pos*+,l,r,v);
else
{
update(pos*,l,mid,v);
update(pos*+,mid+,r,v);
}
tree[pos].maxx = max(tree[pos*].maxx,tree[pos*+].maxx);
} long long getmax(int pos,int l,int r)
{
if(tree[pos].add != )
{
if(tree[pos].left != tree[pos].right)
{
tree[pos*].maxx += tree[pos].add;
tree[pos*].add += tree[pos].add;
tree[pos*+].maxx += tree[pos].add;
tree[pos*+].add += tree[pos].add;
tree[pos].add = ;
}
}
if(tree[pos].left == l && r == tree[pos].right) return tree[pos].maxx;
int mid = (tree[pos].left+tree[pos].right)/;
if(r <= mid) return getmax(pos*,l,r);
if(l > mid) return getmax(pos*+,l,r);
return max(getmax(pos*,l,mid),getmax(pos*+,mid+,r));
} int main()
{
int T;
scanf("%d",&T);
for(int z = ;z <= T;z++)
{
printf("Case #%d:\n",z);
scanf("%d%d",&n,&m);
for(int i = ;i < n;i++) line[i].clear();
for(int i = ;i < n-;i++)
{
int x,y;
scanf("%d%d",&x,&y);
line[x].push_back(y);
line[y].push_back(x);
}
for(int i = ;i < n;i++) scanf("%lld",&w[i]);
cnt = ;
dfs(,,);
build(,,n);
while(m--)
{
int op;
scanf("%d",&op);
if(op == )
{
int x,y;
scanf("%d%d",&x,&y);
long long temp = y-w[x];
w[x] = y;
update(,l[x],r[x],temp);
}
else
{
int x;
scanf("%d",&x);
printf("%lld\n",getmax(,l[x],r[x]));
}
}
}
return ;
}
HDU_5692_dfs序+线段树的更多相关文章
- Educational Codeforces Round 6 E dfs序+线段树
题意:给出一颗有根树的构造和一开始每个点的颜色 有两种操作 1 : 给定点的子树群体涂色 2 : 求给定点的子树中有多少种颜色 比较容易想到dfs序+线段树去做 dfs序是很久以前看的bilibili ...
- 【BZOJ-3252】攻略 DFS序 + 线段树 + 贪心
3252: 攻略 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 339 Solved: 130[Submit][Status][Discuss] D ...
- Codeforces 343D Water Tree(DFS序 + 线段树)
题目大概说给一棵树,进行以下3个操作:把某结点为根的子树中各个结点值设为1.把某结点以及其各个祖先值设为0.询问某结点的值. 对于第一个操作就是经典的DFS序+线段树了.而对于第二个操作,考虑再维护一 ...
- BZOJ2434 [Noi2011]阿狸的打字机(AC自动机 + fail树 + DFS序 + 线段树)
题目这么说的: 阿狸喜欢收藏各种稀奇古怪的东西,最近他淘到一台老式的打字机.打字机上只有28个按键,分别印有26个小写英文字母和'B'.'P'两个字母.经阿狸研究发现,这个打字机是这样工作的: 输入小 ...
- POJ 3321 DFS序+线段树
单点修改树中某个节点,查询子树的性质.DFS序 子树序列一定在父节点的DFS序列之内,所以可以用线段树维护. 1: /* 2: DFS序 +线段树 3: */ 4: 5: #include < ...
- 【XSY2667】摧毁图状树 贪心 堆 DFS序 线段树
题目大意 给你一棵有根树,有\(n\)个点.还有一个参数\(k\).你每次要删除一条长度为\(k\)(\(k\)个点)的祖先-后代链,问你最少几次删完.现在有\(q\)个询问,每次给你一个\(k\), ...
- F - Change FZU - 2277 (DFS序+线段树)
题目链接: F - Change FZU - 2277 题目大意: 题意: 给定一棵根为1, n个结点的树. 有q个操作,有两种不同的操作 (1) 1 v k x : a[v] += x, a[v ' ...
- BZOJ4551[Tjoi2016&Heoi2016]树——dfs序+线段树/树链剖分+线段树
题目描述 在2016年,佳媛姐姐刚刚学习了树,非常开心.现在他想解决这样一个问题:给定一颗有根树(根为1),有以下 两种操作:1. 标记操作:对某个结点打上标记(在最开始,只有结点1有标记,其他结点均 ...
- BZOJ1103 [POI2007]大都市meg dfs序 线段树
欢迎访问~原文出处——博客园-zhouzhendong 去博客园看该题解 题目传送门 - BZOJ1103 题意概括 一棵树上,一开始所有的边权值为1,我们要支持两种操作: 1. 修改某一条边的权值为 ...
随机推荐
- 【转】iOS 7免费设计资源汇总
原文链接:http://mobile.51cto.com/hot-406317.htm#585532-tsina-1-28470-7e393678b940a4d55500bf3feae3d2e9 以下 ...
- 世界500强ING集团顺利的敏捷转型之路
案例背景 为什么银行要像灰狗一样快? 荷兰国际集团(ING),成立于1991年,主营业务银行与保险业务,在全球45个国家和地区拥有分支机构,总资产887亿欧元(2018),全球53,000多名员工,拥 ...
- 微信小程序--百度地图坐标转换成腾讯地图坐标
最近开发小程序时出现一个问题,后台程序坐标采用的时百度地图的坐标,因为小程序地图时采用的腾讯地图的坐标系,两种坐标有一定的误差,导致位置信息显示不正确.现在需要一个可以转换两种坐标的方法,经过查询发现 ...
- 搭建自己的Online Judge
前言 很多人对于做题有点厌烦,但是,如果让你出题给别人做那么可能会很有意思.可是,出题只能出在一些别人的OJ上,甚至只能在自己的Word文档里出.今天我教大家一个厉害点的,叫做搭建自己的Online ...
- mysql的查询优化
参考网站:http://www.liyblog.top/p/6 这里总结了52条对sql的查询优化,下面详细来看看,希望能帮助到你 1, 对查询进行优化,应尽量避免全表扫描,首先应考虑在 wh ...
- Python解析json字符串,json字符串用法
json数据简介 json数据是一个轻量级的数据交换格式,采用完全独立于语言的文本格式,这些特性使json称为理想的数据交换语言,易于人阅读和编写,同时易于机器解析和生成. json中的字符集必须是U ...
- ELK学习实验018:filebeat收集docker日志
Filebeat收集Docker日志 1 安装docker [root@node4 ~]# yum install -y yum-utils device-mapper-persistent-data ...
- 深入学习MySQL 02 日志系统:bin log,redo log,undo log
上一篇文章中,我们了解了一条查询语句的执行过程,按理说这篇应该讲一条更新语句的执行过程,但这个过程比较复杂,涉及到了好几个日志与事物,所以先梳理一下3个重要的日志,bin log(归档日志).redo ...
- mybatis增强工具MyBatis-plus
如果你正在用mybatis,那MyBatis-plus你不能错过,配合使用可极大简化开发.提高效率! 简介 MyBatis-Plus(简称 MP)是一个 MyBatis 的增强工具,在 MyBatis ...
- python3小脚本-监控服务器性能并插入mysql数据库
操作系统: centos版本 7.4 防火墙 关闭 selinux 关闭 python版本 3.6 mysql版本 5.7 #操作系统性能脚本 [root@localhost sql]# cat cp ...