2022.8.5 闲话

发现一个很好玩的东西,

Problem 1

维护一个森林,要求支持:

  • 选中一个节点,求这个节点所在树的直径 .
  • 选中两棵树,连接一条能使得两棵树连接后直径最小的边 .

所有边权都为 1 .

题目来源 .

合并直接并查集,初始的直径先预处理一波 .

观察操作 2,发现一个很显然的结论,就是两棵树中的直径中点连边,连后的直径最小 . 然后观察这两棵树的最长链上的节点个数:

  • 如果两个都是奇链,合并后的中点选合并前的中点的任意一个就可以 .
  • 如果一个是奇链,一个是偶链,合并后的中点选偶链上的那个中点 .
  • 如果两个都是偶链,合并后的中点选合并前的中点的任意一个就可以 .

设连结前 A 树的直径为 da,B 树的直径为 db。很显然,合并后的直径为 dc=da+12+db+12 .

然后在并查集上进行合并和信息向上传递即可 .


以下所有边权都是正数 .

Problem 2

维护一个森林,要求支持:

  • 选中一个节点,求这个节点所在树的直径 .
  • 选中两棵树,连接一条能使得两棵树连接后直径最长的边 .

看起来和 Problem 1 十分相似,但实际上这题简单很多(口胡)

结论:两棵树 T1,T2 的直径分别是 uvxy,则用一条边将两棵树连接后,新直径的端点必然在 {u,v,x,y} 中 .

关于加边动态直径见 Problem 4,这里先放着(伏笔)


Problem 3

给你一棵树,要求支持:

  • 查询子树直径长度 .
  • 删掉一个子树 .

注意到子树操作,于是考虑 DFS 序维护 .

当我们删除一个在 DFS 序上连续的区间时,考虑把两个区间进行合并,这样就是 Problem 2
的结论了 .

合并只需快速计算两点间距离,等价于快速 LCA .

这样最快能做到 O(n) 预处理 O(1) 操作 .

当然作为一个正常人谁写标准 RMQ 啊,但是也别傻乎乎地写倍增,朴素 RMQ 是单次询问 O(1),预处理 O(nlogn) 的,不知道比倍增高到哪里去了 .


Problem 4

给你一个森林,要求支持:

  • 加一条边,保证加完还是树 .
  • 求全局直径 .

注意到加边,于是考虑 LCT .

Problem 2 的性质,只需维护直径端点 .

加边就 LCT 暴力干即可,O(nlogn) .

自带 6 倍常数,还得加上 LCT 巨大常数,刺激!

posted @   yspm  阅读(63)  评论(1编辑  收藏  举报
相关博文:
阅读排行:
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】
😅​
点击右上角即可分享
微信分享提示