Foreword\text{Foreword}Foreword

@zhengrunzhe 大佬的矩阵做法过于神奇,蒟蒻无法理解…
欧拉序的做法确实非常巧妙,但我也想不到这么神仙的做法…
提供一种可能简单一些的 LCT 做法。
由于本人 LCT 无法像大佬那么神,讲的会比较详细一些,也许对其他 LCT 平民玩家更加友好?

Solution\text{Solution}Solution

本题有一个很关键的性质:边权非负。(欧拉序的做法也要基于这个性质)
又发现修改无非改大/小,在/不在原直径上,利用非负的性质分别讨论一下,就会发现新直径至少有一个节点和原来相同
所以我们一开始暴力求出直径后,只需要不断把原直径的两端点提出来,用从二者出发新的最长路径来尝试作为新直径就行了。
所以现在只需要动态维护从一个点出发的最长路径

常规套路,先边化点,边权化点权。
设 wxw_xwx​ 表示 xxx 的点权,sumxsum_xsumx​ 表示 xxx splay子树内点权之和,disxdis_xdisx​ 表示从 xxx 所在 splay 子树内深度最浅的节点出发往子树延伸的最长路径。
先不考虑 xxx 实链父亲,尝试求出从 xxx 出发往子树延伸的最长路径 resxres_xresx​。

一开始有:
resx=wxres_x=w_xresx​=wx​
对于 xxx 的虚儿子,对每个节点开一个 std::set 维护虚子树,进行转移:
resx←max⁡sondisson+wxres_x\gets \max_{son}dis_{son}+w_xresx​←sonmax​disson​+wx​
还有从 xxx 的实儿子转移,不难发现其对应的就是 disrsxdis_{rs_x}disrsx​​:
resx←disrsx+wxres_x\gets dis_{rs_x}+w_xresx​←disrsx​​+wx​
求完 resxres_xresx​ 后,如果 xxx 没有左儿子,说明他就是链头,直接让 disx=resxdis_x=res_xdisx​=resx​ 即可;否则,链头可以不使用 resxres_xresx​ 的转移,或者使用 resxres_xresx​ 的转移,那么还要加上 xxx 到链头一段的权值和,分别对应 max 的前后两项:
disx=max⁡(dislsx,resx+sumlsx)dis_x=\max(dis_{ls_x},res_x+sum_{ls_x})disx​=max(dislsx​​,resx​+sumlsx​​)

这样就做完了。由于转移不对称,所以我们还要镜像的处理一个 dis′xdis'xdis′x,在翻转时直接交换两项即可。

Code\text{Code}Code

#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define ull unsigned long long
#define debug(...) fprintf(stderr,__VA_ARGS__)
#define ok debug("OK\n")
using namespace std;const int N=2e5+100;
inline ll read(){ll x(0),f(1);char c=getchar();while(!isdigit(c)) {if(c=='-')f=-1;c=getchar();}while(isdigit(c)) {x=(x<<1)+(x<<3)+c-'0';c=getchar();}return x*f;
}int n,m;#define pr pair<ll,int>
#define mkp make_pair
pr operator + (const pr &o,const ll &w){return mkp(o.first+w,o.second);}int tr[N][2],rev[N],f[N];
ll sum[N],w[N];
pr dis1[N],dis2[N];
multiset<pr>s[N];
#define ls(x) tr[x][0]
#define rs(x) tr[x][1]
inline bool nroot(int x){return ls(f[x])==x||rs(f[x])==x;}
inline bool which(int x){return rs(f[x])==x;}inline void pushup(int x){sum[x]=w[x]+sum[ls(x)]+sum[rs(x)];dis1[x]=s[x].empty()?mkp(w[x],x<=n?x:-1):(*s[x].rbegin())+w[x];if(rs(x)) dis1[x]=max(dis1[x],dis1[rs(x)]+w[x]);if(ls(x)) dis1[x]=max(dis1[ls(x)],dis1[x]+sum[ls(x)]);dis2[x]=s[x].empty()?mkp(w[x],x<=n?x:-1):(*s[x].rbegin())+w[x];if(ls(x)) dis2[x]=max(dis2[x],dis2[ls(x)]+w[x]);if(rs(x)) dis2[x]=max(dis2[rs(x)],dis2[x]+sum[rs(x)]);return;
}
inline void Rev(int x){if(x){rev[x]^=1;swap(ls(x),rs(x));swap(dis1[x],dis2[x]);}return;
}
inline void pushdown(int x){if(rev[x]){rev[x]=0;Rev(ls(x));Rev(rs(x));}return;
}
void dfs(int x){if(!x) return;pushdown(x);debug("x=%d f=%d ls=%d rs=%d w=%lld dis1=(%lld %d) s: ",x,f[x],ls(x),rs(x),w[x],dis1[x].first,dis1[x].second);for(pr o:s[x]) debug("(%lld %d) ",o.first,o.second);debug("\n");dfs(ls(x));dfs(rs(x));
}
void print(){for(int i=1;i<=n+n-1;i++){if(!nroot(i)) dfs(i);}
}
inline void rotate(int x){int fa=f[x],gfa=f[fa];int d=which(x),son=tr[x][d^1];f[x]=gfa;if(nroot(fa)) tr[gfa][which(fa)]=x;f[fa]=x;tr[x][d^1]=fa;if(son) {f[son]=fa;}tr[fa][d]=son;pushup(fa);pushup(x);return;
}
int zhan[N];
inline void splay(int x){int top=0,y=x;zhan[++top]=y;while(nroot(y)) zhan[++top]=y=f[y];while(top) pushdown(zhan[top--]);for(int fa;fa=f[x],nroot(x);rotate(x)){if(nroot(fa)) which(fa)==which(x)?rotate(fa):rotate(x);}return;
}
inline void access(int x){for(int y=0;x;y=x,x=f[x]){splay(x);if(rs(x)){s[x].insert(dis1[rs(x)]);}if(y){s[x].erase(s[x].find(dis1[y]));}rs(x)=y;pushup(x);}return;
}
inline void makeroot(int x){access(x);splay(x);Rev(x);
}
inline void link(int x,int y){makeroot(x);makeroot(y);f[x]=y;s[y].insert(dis1[x]);pushup(y);return;
}ll mod;
ll D;
int a,b;
signed main(){#ifndef ONLINE_JUDGEfreopen("a.in","r",stdin);freopen("a.out","w",stdout);#endifn=read();m=read();mod=read();for(int i=1;i<n;i++){int x=read(),y=read();w[n+i]=read();link(x,n+i);link(y,n+i);}for(int i=1;i<=n;i++){makeroot(i);if(dis1[i].first>D){D=dis1[i].first;a=i;b=dis1[i].second;}}ll lst=0;while(m--){ll x=(read()+lst)%(n-1)+1 +n,ww=(read()+lst)%mod;    makeroot(x);w[x]=ww;pushup(x);int u=a,v=b;D=a=b=0;makeroot(u);if(dis1[u].first>=D){D=dis1[u].first;a=u;b=dis1[u].second;}makeroot(v);if(dis1[v].first>=D){D=dis1[v].first;a=v;b=dis1[v].second;}printf("%lld\n",lst=D);}return 0;
}
/*
*/

CF1192B Dynamic Diameter(LCT)相关推荐

  1. AAA 服务器 — Diameter(直径)协议

    目录 文章目录 目录 Diameter 协议簇 Diameter 实现的组成部分 Diameter 协议簇的基本协议 Diameter 协议簇的应用协议 freeDiameter 开源实现 Diame ...

  2. SpringBoot整合Mybatis3 Dynamic Sql(IDEA)

    SpringBoot整合Mybatis3 Dynamic Sql(IDEA) Mybatis Dynamic Sql与以前TargetRuntime相比较: 移除了XXXExamle类和xml文件,代 ...

  3. 动态树(LCT)初探

    文章目录 前置技能 那么直接开始吧 原树与辅助树 Access操作 含义 Addition: Splay 旋转操作 Splay操作 辅助树上的Access MakeRoot操作 Link操作 Cut操 ...

  4. 模板:Link Cut Tree(LCT)

    文章目录 前言 解析 原理 rotate(x) splay(x) access(x) findroot(x) makeroot(x) split(x,y) link(x,y) cut(x,y) pus ...

  5. Unity 2017 Game Optimization 读书笔记 Dynamic Graphics(2)

    Lighting and Shadowing 现代的游戏中,基本没有物体能在一步就完成渲染,这是因为有光照和阴影的关系.光照和阴影的渲染在Fragment Shader中需要额外的pass. 首先要设 ...

  6. Unity 2017 Game Optimization 读书笔记 Dynamic Graphics(1)

    The Rendering Pipeline 渲染表现差有可能取决于CPU端(CPU Bound)也有可能取决于GPU(GPU Bound).调查CPU-bound的问题相对简单,因为CPU端的工作就 ...

  7. @property、@sythesize以及Ivar和@dynamic讲解(下)

    下面仅仅是一些基本知识,可能有些知识用的比较少,不过知道怎么使用或者了解这个知识,还是不错的,毕竟技多不压身嘛!读完这篇文章大约需要5-10分钟左右!!! 一.@property 1.在头文件中: @ ...

  8. BZOJ5212 ZJOI2018历史(LCT)

    首先相当于最大化access的轻重边交换次数. 考虑每个点作为战场(而不是每个点所代表的国家与其他国家交战)对答案的贡献,显然每次产生贡献都是该点的子树内(包括自身)此次access的点与上次acce ...

  9. CF1491H Yuezheng Ling and Dynamic Tree(分块)

    CF1491H Yuezheng Ling and Dynamic Tree description solution code description 题目链接 solution 非常清新的小分块题 ...

最新文章

  1. 使用iso文件安装双系统linux,Win7下使用EasyBcd安装Ubuntu(iso文件)双系统
  2. 【网络安全】HTB靶机渗透系列之Sniper
  3. vue面试题,知识点汇总(有答案)
  4. wince 环境变量
  5. 简直要逆天!超炫的 HTML5 粒子效果进度条
  6. LintCode 158: Anagram
  7. 为AI芯片铺路?原三星半导体周军加盟Rokid
  8. 如何虚拟打印PDF文件(Win7)
  9. 主板怎么开启csm_手把手教你查看电脑主板是否支持UEFI+GPT启动模式-网络教程与技术 -亦是美网络...
  10. selenium IED安装
  11. java 计算经度纬度之间的距离
  12. 前端优化——前端面试
  13. 服务器微信了早上好,微信早上好祝福语大全
  14. xilinx c语言u16,Xilinx FPGA LVDS应用
  15. 编写CSDN博客,如何去掉插入的图片上的水印
  16. 巧得cos平方的均值——妙啊!
  17. 笔记——三维世界坐标和二维画布/屏幕坐标转换
  18. Win10历史记录怎么查
  19. 同构处理器和异构处理器的区别
  20. 组态王 6.55 启停plc_PLC串口通讯和通讯接口知识

热门文章

  1. java 学习思路_Java的学习思路
  2. python3 2.00gb怎么去掉单位_最值得期待的Python 3.9的新功能
  3. 湖南工业职业技术学院计算机协会,计算机网络协会
  4. python离群点检测_如何从熊猫DataFrame中检测峰点(离群值)
  5. c语言中文件如何插入数据,急求如何将下列C语言程序数据存储到文件中?
  6. python变量类型怎么决定的_Python数据类型提示痛点的解决方案探讨
  7. linux监控目录容量,利用ZABBIX监控某个目录大小
  8. mysql闪回工具下载_MySQL闪回工具之myflash 和 binlog2sql
  9. Java多线程之龟兔赛跑和抢票
  10. 计算机检测维修与数据恢复课件,2017年全国职业院校技能大赛中职组“计算机检测维修与数据恢复”赛项说明会ppt课件.ppt...