CF1192B Dynamic Diameter(LCT)
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←maxsondisson+wxres_x\gets \max_{son}dis_{son}+w_xresx←sonmaxdisson+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)相关推荐
- AAA 服务器 — Diameter(直径)协议
目录 文章目录 目录 Diameter 协议簇 Diameter 实现的组成部分 Diameter 协议簇的基本协议 Diameter 协议簇的应用协议 freeDiameter 开源实现 Diame ...
- SpringBoot整合Mybatis3 Dynamic Sql(IDEA)
SpringBoot整合Mybatis3 Dynamic Sql(IDEA) Mybatis Dynamic Sql与以前TargetRuntime相比较: 移除了XXXExamle类和xml文件,代 ...
- 动态树(LCT)初探
文章目录 前置技能 那么直接开始吧 原树与辅助树 Access操作 含义 Addition: Splay 旋转操作 Splay操作 辅助树上的Access MakeRoot操作 Link操作 Cut操 ...
- 模板:Link Cut Tree(LCT)
文章目录 前言 解析 原理 rotate(x) splay(x) access(x) findroot(x) makeroot(x) split(x,y) link(x,y) cut(x,y) pus ...
- Unity 2017 Game Optimization 读书笔记 Dynamic Graphics(2)
Lighting and Shadowing 现代的游戏中,基本没有物体能在一步就完成渲染,这是因为有光照和阴影的关系.光照和阴影的渲染在Fragment Shader中需要额外的pass. 首先要设 ...
- Unity 2017 Game Optimization 读书笔记 Dynamic Graphics(1)
The Rendering Pipeline 渲染表现差有可能取决于CPU端(CPU Bound)也有可能取决于GPU(GPU Bound).调查CPU-bound的问题相对简单,因为CPU端的工作就 ...
- @property、@sythesize以及Ivar和@dynamic讲解(下)
下面仅仅是一些基本知识,可能有些知识用的比较少,不过知道怎么使用或者了解这个知识,还是不错的,毕竟技多不压身嘛!读完这篇文章大约需要5-10分钟左右!!! 一.@property 1.在头文件中: @ ...
- BZOJ5212 ZJOI2018历史(LCT)
首先相当于最大化access的轻重边交换次数. 考虑每个点作为战场(而不是每个点所代表的国家与其他国家交战)对答案的贡献,显然每次产生贡献都是该点的子树内(包括自身)此次access的点与上次acce ...
- CF1491H Yuezheng Ling and Dynamic Tree(分块)
CF1491H Yuezheng Ling and Dynamic Tree description solution code description 题目链接 solution 非常清新的小分块题 ...
最新文章
- 使用iso文件安装双系统linux,Win7下使用EasyBcd安装Ubuntu(iso文件)双系统
- 【网络安全】HTB靶机渗透系列之Sniper
- vue面试题,知识点汇总(有答案)
- wince 环境变量
- 简直要逆天!超炫的 HTML5 粒子效果进度条
- LintCode 158: Anagram
- 为AI芯片铺路?原三星半导体周军加盟Rokid
- 如何虚拟打印PDF文件(Win7)
- 主板怎么开启csm_手把手教你查看电脑主板是否支持UEFI+GPT启动模式-网络教程与技术
-亦是美网络...
- selenium IED安装
- java 计算经度纬度之间的距离
- 前端优化——前端面试
- 服务器微信了早上好,微信早上好祝福语大全
- xilinx c语言u16,Xilinx FPGA LVDS应用
- 编写CSDN博客,如何去掉插入的图片上的水印
- 巧得cos平方的均值——妙啊!
- 笔记——三维世界坐标和二维画布/屏幕坐标转换
- Win10历史记录怎么查
- 同构处理器和异构处理器的区别
- 组态王 6.55 启停plc_PLC串口通讯和通讯接口知识
热门文章
- java 学习思路_Java的学习思路
- python3 2.00gb怎么去掉单位_最值得期待的Python 3.9的新功能
- 湖南工业职业技术学院计算机协会,计算机网络协会
- python离群点检测_如何从熊猫DataFrame中检测峰点(离群值)
- c语言中文件如何插入数据,急求如何将下列C语言程序数据存储到文件中?
- python变量类型怎么决定的_Python数据类型提示痛点的解决方案探讨
- linux监控目录容量,利用ZABBIX监控某个目录大小
- mysql闪回工具下载_MySQL闪回工具之myflash 和 binlog2sql
- Java多线程之龟兔赛跑和抢票
- 计算机检测维修与数据恢复课件,2017年全国职业院校技能大赛中职组“计算机检测维修与数据恢复”赛项说明会ppt课件.ppt...