[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\)点最远的点的距离. 分析 官方题解做法:动态维 ...
随机推荐
- HDU4742 CDQ分治,三维LIS
HDU4742 CDQ分治,三维LIS 传送门:http://acm.hdu.edu.cn/showproblem.php?pid=4742 题意: 每个球都有三个属性值x,y,z,要求最长的lis的 ...
- codeforces 86D,Powerful array 莫队
传送门:https://codeforces.com/contest/86/problem/D 题意: 给你n个数,m次询问,每次询问问你在区间l,r内每个数字出现的次数的平方于当前这个数的乘积的和 ...
- web.config修改文件修改上传大小
老是要修改上传文件大小的限制,先记在这里. <httpRuntime maxRequestLength= "1048576 " //最大长度 executionTimeout ...
- VRChat之转移地图缓存
我的电脑是win10,win10的缓存地址和名称可能和win7的名字有所不同. win10缓存路径:C:\Users\Administrator\AppData\LocalLow\VRChat\VRC ...
- 驱动领域DDD的微服务设计和开发实战
你是否还在为微服务应该拆多小而争论不休?到底如何才能设计出收放自如的微服务?怎样才能保证业务领域模型与代码模型的一致性?或许本文能帮你找到答案. 本文是基于 DDD 的微服务设计和开发实战篇,通过借鉴 ...
- 雪花算法 Snowflake & Sonyflake
唯一ID算法Snowflake相信大家都不墨生,他是Twitter公司提出来的算法.非常广泛的应用在各种业务系统里.也因为Snowflake的灵活性和缺点,对他的改造层出不穷,比百度的UidGener ...
- DEVOPS技术实践_13:使用Jenkins持续传送设计-CD基础
1. 分支策略 持续集成中使用的分支策略包括以下三个: The master branch The integration branch The feature branch 而CD只在Integra ...
- $CF912E\ Prime\ Gift$ 二分+搜索
正解:二分+搜索 解题报告: 传送门$QwQ$ 因为翻译真的很$umm$所以还是写下题目大意$QwQ$,就说给定一个大小为$n$的素数集合,求出分解后只含这些质数因子的第$K$小整数 考虑先把质数分两 ...
- $Luogu2680/NOIp2015$ 运输计划
传送门 $Sol$ 最暴力的做法就是枚举最长链上的边,然后再算一次所有的链长,更新$ans$. 这里要求最大的最小,容易想到二分答案.对于二分的值$mid$,扫一遍所有的链,若链长小于等于$mid$, ...
- 博帝飚速盘 16G
设备制造商: Patriot Memory当前协议 : USB2.0输入电流 : 300mA 芯片制造商: 群联(Phison)芯片型号 : PS2251-38闪存颗粒 : 美光( ...