Time:2016.05.26
Author:xiaoyimi
转载注明出处谢谢


传送门
思路:
(调了好久发现是链剖打错了)
线性版本的话可以去看水果姐逛水果店Ⅰ
这个放到了树上,还加了个修改操作
先链剖,再维护最大值及最小值,左->右最大差值,右->左最大差值
区间修改打标记
线段树上的连续区间维护起来很好办
关键就在于怎么维护询问中访问的所有链的信息
之前没有写过类似这样的,向char哥学习了一下,具体就是线段树查询时返回线段树的数据类型的节点,来存储和维护信息。
细节信息个人推荐看代码
注意:
很容易把左右,大小,深浅这些东西搞混了……最后就不知所措= =
代码:

#include<cstdio>
#include<cstring>
#include<iostream>
#define M 50003
#define inf 0x7ffffff
using namespace std;
int n,q,tot,cnt;
int w[M],fa[M],son[M],siz[M],top[M],dep[M],L[M],pre[M],first[M],lazy[M<<2];
struct edge{int v,next;}e[M<<1];
struct seg
{int sum_L,sum_R,maxn,minn;//sum_L->由深到浅(线段树区间由大到小走),sum_R->由浅到深(线段树区间由小到大)
}tree[M<<2];
seg Null={-inf,-inf,-inf,inf};
int in()
{int t=0;char ch=getchar();bool f=0;while (!isdigit(ch)) f=(ch=='-'),ch=getchar();while (isdigit(ch)) t=(t<<1)+(t<<3)+ch-48,ch=getchar();return f?-t:t;
}
void add(int x,int y)
{e[++tot]=(edge){y,first[x]};first[x]=tot;e[++tot]=(edge){x,first[y]};first[y]=tot;
}
void dfs1(int x)
{siz[x]=1;for (int i=first[x];i;i=e[i].next)if (e[i].v!=fa[x])fa[e[i].v]=x,dep[e[i].v]=dep[x]+1,dfs1(e[i].v),siz[x]+=siz[e[i].v],son[x]=(siz[son[x]]>siz[e[i].v]?son[x]:e[i].v);
}
void dfs2(int x,int tp)
{L[x]=++cnt;pre[cnt]=x;top[x]=tp;if (son[x]) dfs2(son[x],tp);else return;for (int i=first[x];i;i=e[i].next)if (e[i].v!=fa[x]&&e[i].v!=son[x]) dfs2(e[i].v,e[i].v);
}
void pushup(int now)
{tree[now].maxn=max(tree[now<<1].maxn,tree[now<<1|1].maxn);tree[now].minn=min(tree[now<<1].minn,tree[now<<1|1].minn);tree[now].sum_L=max(tree[now<<1].maxn-tree[now<<1|1].minn,max(tree[now<<1].sum_L,tree[now<<1|1].sum_L));tree[now].sum_R=max(tree[now<<1|1].maxn-tree[now<<1].minn,max(tree[now<<1].sum_R,tree[now<<1|1].sum_R));
}
void pushdown(int now)
{if (!lazy[now]) return;tree[now<<1].maxn+=lazy[now]; tree[now<<1].minn+=lazy[now];lazy[now<<1]+=lazy[now]; lazy[now<<1|1]+=lazy[now];tree[now<<1|1].maxn+=lazy[now];tree[now<<1|1].minn+=lazy[now];lazy[now]=0;
}
void build(int now,int begin,int end)
{if (begin==end){tree[now]=(seg){0,0,w[pre[end]],w[pre[end]]};return;}int mid=begin+end>>1;build(now<<1,begin,mid);build(now<<1|1,mid+1,end);pushup(now);
}
void update(int now,int begin,int end,int l,int r,int val)
{if (l<=begin&&end<=r){lazy[now]+=val;tree[now].maxn+=val;tree[now].minn+=val;return;}pushdown(now);int mid=begin+end>>1;if (mid>=l) update(now<<1,begin,mid,l,r,val);if (mid<r) update(now<<1|1,mid+1,end,l,r,val);pushup(now);
}
seg get(int now,int begin,int end,int l,int r)
{if (l<=begin&&end<=r) return tree[now];pushdown(now);int mid=begin+end>>1;if (mid>=r)return get(now<<1,begin,mid,l,r);else if (mid<l)return get(now<<1|1,mid+1,end,l,r);seg ans,t1=get(now<<1,begin,mid,l,r),t2=get(now<<1|1,mid+1,end,l,r);ans.maxn=max(t1.maxn,t2.maxn);ans.minn=min(t1.minn,t2.minn);ans.sum_L=max(max(t1.sum_L,t2.sum_L),t1.maxn-t2.minn);ans.sum_R=max(max(t1.sum_R,t2.sum_R),t2.maxn-t1.minn);return ans;
}
main()
{n=in();for (int i=1;i<=n;i++) w[i]=in();for (int i=1;i<n;i++) add(in(),in());dfs1(1);dfs2(1,1);build(1,1,n);q=in();int x,y,z;while (q--){x=in();y=in();z=in();seg ans_L=Null,ans_R=Null,t;for (int f1=top[x],f2=top[y];f1!=f2;){if (dep[f1]<dep[f2])t=get(1,1,n,L[f2],L[y]),ans_R.sum_R=max(max(ans_R.sum_R,t.sum_R),ans_R.maxn-t.minn),ans_R.maxn=max(ans_R.maxn,t.maxn),ans_R.minn=min(ans_R.minn,t.minn),update(1,1,n,L[f2],L[y],z),y=fa[f2],f2=top[y];elset=get(1,1,n,L[f1],L[x]),ans_L.sum_L=max(max(ans_L.sum_L,t.sum_L),t.maxn-ans_L.minn),ans_L.maxn=max(ans_L.maxn,t.maxn),ans_L.minn=min(ans_L.minn,t.minn),update(1,1,n,L[f1],L[x],z),x=fa[f1],f1=top[x];}if (dep[x]<=dep[y])t=get(1,1,n,L[x],L[y]),ans_R.sum_R=max(max(ans_R.sum_R,t.sum_R),ans_R.maxn-t.minn),ans_R.maxn=max(ans_R.maxn,t.maxn),ans_R.minn=min(ans_R.minn,t.minn),update(1,1,n,L[x],L[y],z);elset=get(1,1,n,L[y],L[x]),ans_L.sum_L=max(max(ans_L.sum_L,t.sum_L),t.maxn-ans_L.minn),ans_L.maxn=max(ans_L.maxn,t.maxn),ans_L.minn=min(ans_L.minn,t.minn),update(1,1,n,L[y],L[x],z);printf("%d\n",max(ans_R.maxn-ans_L.minn,max(ans_L.sum_L,ans_R.sum_R)));}
}

【BZOJ3999】旅游,树链剖分中的有向信息合并相关推荐

  1. P1505 [国家集训队]旅游 树链剖分

    题目链接 题意:树上更新某一点权值,更新两点简单路径权值,查询最大,最小,和 思路:思路应该比较简单,就是树链剖分后用线段树维护区间最大最小以及区间和. 但是本题比较特殊的是给的边权,转化为点权即可. ...

  2. 树链剖分中的重链剖分

    更多文章可以在本人的个人小站:https://kaiserwilheim.github.io 查看. 转载请注明出处. 引言 树链剖分(简称"树剖",又称"重链剖分&qu ...

  3. 蒟蒻浅谈树链剖分之一——两个dfs操作

    树链剖分,顾名思义就是将树形的结构剖分成链,我们以此便于在链上操作 首先我们需要明白在树链剖分中的一些概念 重儿子:某节点所有儿子中子树最多的儿子 重链:有重儿子构成的链 dfs序:按重儿子优先遍历时 ...

  4. BZOJ 2243 染色(树链剖分好题)

    2243: [SDOI2011]染色 Time Limit: 20 Sec  Memory Limit: 512 MB Submit: 7971  Solved: 2990 [Submit][Stat ...

  5. HDU 3966 POJ 3237 HYSBZ 2243 HRBUST 2064 树链剖分

    树链剖分是一个很固定的套路 一般用来解决树上两点之间的路径更改与查询 思想是将一棵树分成不想交的几条链 并且由于dfs的顺序性 给每条链上的点或边标的号必定是连着的 那么每两个点之间的路径都可以拆成几 ...

  6. 【树链剖分】Disruption P(luogu 4374)

    正题 luogu 4374 题目大意 给你一棵树,还有若干边,每条边有一定代价,问你删掉树中的每条边后,使其成为连通图的最小代价 解题思路 不难发现,一条边只对两个端点在树中的路径上的边有贡献(即删去 ...

  7. ⌈洛谷1505⌋⌈BZOJ2157⌋⌈国家集训队⌋旅游【树链剖分】

    题目链接 [洛谷] [BZOJ] 题目描述 Ray 乐忠于旅游,这次他来到了T 城.T 城是一个水上城市,一共有 N 个景点,有些景点之间会用一座桥连接.为了方便游客到达每个景点但又为了节约成本,T ...

  8. BZOJ 2157 「国家集训队」旅游(树链剖分,线段树,边权转点权)【BZOJ计划】

    整理的算法模板合集: ACM模板 点我看算法全家桶系列!!! 实际上是一个全新的精炼模板整合计划 题目链接 https://hydro.ac/d/bzoj/p/2157 是 hydro 的 BZOJ ...

  9. bzoj 3999: [TJOI2015]旅游(树链剖分)

    3999: [TJOI2015]旅游 Time Limit: 10 Sec  Memory Limit: 256 MB Submit: 423  Solved: 214 [Submit][Status ...

最新文章

  1. android 多种特效TextView
  2. 2.3线性表的链式存储和运算—双向链表
  3. 嘉楠勘智 K210 RISC-V 64位双核处理器开发板(荔枝丹)
  4. 微软将弃用 System.Data.OracleClient
  5. ArcGIS中通过JPG图片文件提取矢量要素
  6. 如何修复rpc服务器,打印时弹出RPC服务器不可用修复教程
  7. android ppt的动画效果怎么做,Android 仿 PPT 进入动画效果合集
  8. 金色传说:SAP-ABAP-销售订单增强:记录销售订单修改信息和修改原因
  9. 文科生学计算机能考研吗,求推荐文科生可以跨考计算机的名校
  10. 《游戏机制——高级游戏设计技术》一1.1 规则定义游戏
  11. JAVA的诞生及版本
  12. 【谷歌地图--MapsSDK集成】
  13. jvm基础学习总结笔记
  14. 燕山大学课程实践项目报告:ISBN号识别系统的设计与开发
  15. ajaxsubmit php上传文件,怎样用AjaxSubmit()提交file文件
  16. 用Python搭建一个股票舆情分析系统
  17. java序列化,从底层到序列化所隐藏的问题以及解决方案
  18. 中心极限定理和泊松分布的条件
  19. 使用librosa进行语音情感识别
  20. 国密SM9算法C++实现之六:密钥封装解封算法

热门文章

  1. 开源大数据平台HBase对接OBS操作指南
  2. 【华为云实战开发】2.Docker镜像部署怎么玩才酷炫?
  3. php二分法 冒泡 快速排序,PHP 常见算法【冒泡排序, 快速排序, 插入排序, 取舍排序, 二分法查找, .】...
  4. Spark内核解析2
  5. Hadoop简介与分布式安装
  6. WORD如何隐藏选中内容?
  7. python函数定义时参数相当于占位符_python中函数的参数
  8. java 异常处理线程_转:Java子线程中的异常处理(通用)
  9. project不显示里程碑标志_3万台!纽荷兰大方捆打捆机再创全新里程碑
  10. 软件测试常见笔试面试题(一)