[CF1192B]动态直径
题意
给一棵固定形态的树,边有边权,每次修改一条边权,在线求出修改后树的直径。
思考
写出树的全dfs序。生成方式为:每当一个点进栈或入栈时,记录它的编号。
考虑这个dfs序上两点之间的距离。设某个节点在dfs序中第一次出现的位置为$where_i$,第i个位置的节点为$what_i$两个点分别为u和v。可以发现,在dfs上,u和v之间一堆会包含它们的lca,则:
$$dis_{u,v}=max_{where_u \leq x \leq where_v}{\{dep_u+dep_v-2*dep_{what_x}\}}$$
树的直径即为上述表达式的最大值。
考虑到直径的形式为u-lca-v的形式,我们可以在dfs序上看成是L、M、R的这三部分组成,其中L和R要尽可能大,M要尽可能小(代码中先加了符号,所以还是最大的)。考虑线段树,维护当前区间的最大值、M、LM、MR和LMR,最后的答案即为线段树根节点的LMR。不难证明,可以进行如下合并:
$val=max{\{val_l,val_r\}}$
$M=max{\{M_l,M_r\}}$(取了负号)
$LM=max{\{LM_l,LM_r,val_l+M_r\}}$
$MR=max{\{RM_l,RM_r,M_l+val_r\}}$
$LMR=max{\{LMR_l,LMR_r,LM_l+val_r,val_l+RM_r\}}$
对于修改操作,相当于是区间修改,直接打标记即可。
时间复杂度:$O(n+qlogn)$
代码
// luogu-judger-enable-o2
#include<bits/stdc++.h>
using namespace std;
const int maxn=1E5+;
typedef long long int ll;
int n,m;
int size=,head[maxn*];
int dfn,dfnFirst[maxn],dfnLast[maxn],what[maxn*],fa[maxn];
ll lastans,weight[maxn],dep[maxn];
ll val[maxn*],M[maxn*],LM[maxn*],MR[maxn*],LMR[maxn*],tag[maxn*];
struct edge
{
int to,next;
ll w;
}E[maxn*];
inline void addE(int u,int v,ll w)
{
E[++size].to=v;
E[size].next=head[u];
E[size].w=w;
head[u]=size;
}
void dfs(int u,int F,ll d)
{
what[dfnFirst[u]=++dfn]=u;
dep[u]=d;
fa[u]=F;
for(int i=head[u];i;i=E[i].next)
{
int v=E[i].to;
if(v==F)
continue;
weight[v]=E[i].w;
dfs(v,u,d+E[i].w);
what[++dfn]=u;
}
dfnLast[u]=dfn;
}
inline void pushdown(int l,int r,int num)
{
val[num]+=tag[num];
M[num]-=tag[num]*;
LM[num]-=tag[num];
MR[num]-=tag[num];
if(l!=r)
tag[num<<]+=tag[num],tag[num<<|]+=tag[num];
tag[num]=;
}
inline void update(int l,int r,int num)
{
if(l==r)
return;
val[num]=max(val[num<<],val[num<<|]);
M[num]=max(M[num<<],M[num<<|]);
LM[num]=max(max(LM[num<<],LM[num<<|]),val[num<<]+M[num<<|]);
MR[num]=max(max(MR[num<<],MR[num<<|]),M[num<<]+val[num<<|]);
LMR[num]=max(max(LMR[num<<],LMR[num<<|]),max(LM[num<<]+val[num<<|],val[num<<]+MR[num<<|]));
}
void build(int l,int r,int num)
{
if(l==r)
{
int pos=what[l];
val[num]=dep[pos];
M[num]=-*dep[pos];
LM[num]=MR[num]=-dep[pos];
return;
}
int mid=(l+r)>>;
build(l,mid,num<<),build(mid+,r,num<<|);
update(l,r,num);
}
void add(int L,int R,int l,int r,ll x,int num)
{
if(L<=l&&r<=R)
{
tag[num]+=x;
pushdown(l,r,num);
return;
}
pushdown(l,r,num);
int mid=(l+r)>>;
if(R<=mid)
add(L,R,l,mid,x,num<<);
else if(mid<L)
add(L,R,mid+,r,x,num<<|);
else
add(L,R,l,mid,x,num<<),add(L,R,mid+,r,x,num<<|);
pushdown(l,mid,num<<);
pushdown(mid+,r,num<<|);
update(l,r,num);
}
int main()
{
ios::sync_with_stdio(false);
ll W;
cin>>n>>m>>W;
for(int i=;i<=n;++i)
{
int x,y;
ll z;
cin>>x>>y>>z;
addE(x,y,z);
addE(y,x,z);
}
dfs(,,);
build(,*n-,);
while(m--)
{
ll x,y;
cin>>x>>y;
x=(x+lastans)%(n-)+;
y=(y+lastans)%W;
if(fa[E[x<<].to]==E[x<<|].to)
x=E[x<<].to;
else
x=E[x<<|].to;
add(dfnFirst[x],dfnLast[x],,*n-,y-weight[x],);
weight[x]=y;
lastans=LMR[];
cout<<lastans<<endl;
}
return ;
}
[CF1192B]动态直径的更多相关文章
- 2019 ICPC上海网络赛 A 题 Lightning Routing I (动态维护树的直径)
题目: 给定一棵树, 带边权. 现在有2种操作: 1.修改第i条边的权值. 2.询问u到其他一个任意点的最大距离是多少. 题解: 树的直径可以通过两次 dfs() 的方法求得.换句话说,到任意点最远的 ...
- 「校内训练 2019-04-23」越野赛车问题 动态dp+树的直径
题目传送门 http://192.168.21.187/problem/1236 http://47.100.137.146/problem/1236 题解 题目中要求的显然是那个状态下的直径嘛. 所 ...
- iOS 实现脉冲雷达以及动态增减元素 By Swift-感谢分享
Swift经过Xcode6 Beta4一版更新后,基本上已经可以作为生产工具了,虽然有一些地方和ObjC比起来要“落后”一些,但也无伤大雅.这里就用Xcode6 Beta4+iOS SDK 8.0开发 ...
- #6145. 「2017 山东三轮集训 Day7」Easy 动态点分治
\(\color{#0066ff}{题目描述}\) JOHNKRAM 最近在参加 C_SUNSHINE 举办的聚会. C 国一共有 n 座城市,这些城市由 n−1 条无向道路连接.任意两座城市之间有且 ...
- 【BZOJ1095】[ZJOI2007]Hide 捉迷藏 动态树分治+堆
[BZOJ1095][ZJOI2007]Hide 捉迷藏 Description 捉迷藏 Jiajia和Wind是一对恩爱的夫妻,并且他们有很多孩子.某天,Jiajia.Wind和孩子们决定在家里玩捉 ...
- [LOJ#121]动态图连通性
[LOJ#121]动态图连通性 试题描述 这是一道模板题. 你要维护一张无向简单图.你被要求加入删除一条边及查询两个点是否连通. 0:加入一条边.保证它不存在. 1:删除一条边.保证它存在. 2:查询 ...
- 0x63树的直径与最近公共祖先
凉 bzoj1999 先把树的直径求出来,从左往右枚举,对于当前位置i,找到满足限制并且最远的点j,当前位置最大值就是max(i~j区间内除直径外的子树路径长度最大值,1~i的长度,j~n的长度) 然 ...
- 小程序开发笔记【五】---基于LBS附近动态查询
实现思路 : 获取用户当前位置经纬度坐标 查询动态时将经纬度坐标传给后台 后端通过sql语句计算经纬度坐标之间的距离 // 附近20公里发的动态 按时间排序 let sql = `SELECT * , ...
- 2019ICPC上海网络赛 A Lightning Routing I 点分树(动态点分治)+线段树
题意 给一颗带边权的树,有两种操作 \(C~e_i~w_i\),将第\(e_i\)条边的边权改为\(w_i\). \(Q~v_i\),询问距\(v_i\)点最远的点的距离. 分析 官方题解做法:动态维 ...
随机推荐
- Centos7网络连接不上:Network is unreachable 解决方案
有朋友的centos7装在虚拟机上挂起后在打开不能正常连接网络,我的也出现了这个问题,试着用dhclient重新分配一下地址,无奈系统提示dhclient正在运行,没办法只能试试其它办法,之后研究了一 ...
- Hibernate管理Session
Hibernate自身提供了三种管理Session对象的方法 Session对象的生命周期与本地线程绑定 Session对象的生命周期与JTA事务绑定 Hibernate委托程序管理Session对象 ...
- CodeTypeDeclaration,CodeMemberProperty动态生成代码
由于是CodeDom些列,所以先介绍几个CodeDom表达式: :CodeConditionStatement:判断语句即是if(condition){} else{},看最全的那个构造函数: pub ...
- kotlin + springboot整合mybatis操作mysql数据库及单元测试
项目mybatis操作数据库参考: http://how2j.cn/k/springboot/springboot-mybatis/1649.html?p=78908 junit对controller ...
- javascript DOM 编程艺术 札记2 平稳退化
定义 指的是即便浏览器不支持javascript,页面的基础展示功能也不会受到影响的做法. 不能平稳退化的实例 javascript:这种伪协议,它可以通过链接调用javascript函数.比如< ...
- javascript DOM 编程艺术 札记1
一个重要观点 DOM 是指 文档对象模型,它对应浏览器实际认知的东西.html 文本本身和 html 加载到浏览器中显示的东西并不是完全一致的,后者就是 DOM 节点树,它是浏览器实际认知的东西.一个 ...
- 敏捷开发:代码Review
热情高涨 代码走查作为一种流程形式,起初大家的参与热情非常高涨. 因为,自己可以学习到别人一些巧妙的思想,自己的代码和习惯都暴漏出来. 这个过程中不断地吸收和改正. 但是...... 我们一开始组织的 ...
- 「Luogu P4987」回文项链 解题报告
题面 求环中的长度为k(k为奇数)且回文中心不同的回文串个数 思路: 刚学manacher算法,就送上一道模板题,此题注重对manacher算法的理解 Manacher,但是不用插入其他符号,因为k是 ...
- 1073 多选题常见计分法 (20分)C语言
批改多选题是比较麻烦的事情,有很多不同的计分方法.有一种最常见的计分方法是:如果考生选择了部分正确选项,并且没有选择任何错误选项,则得到 50% 分数:如果考生选择了任何一个错误的选项,则不能得分.本 ...
- SpringCloud入门系列0-Nacos的安装与配置
背景 工作有一些年头了,自从19年初彻底转了java(这又是另一篇心酸的故事),突然感觉自己荒废了好几年(不是说.net不好,而是回顾自己这几年做的很多东西都浮于表面,有时候弄成很忙的样子,回头看看自 ...