Xor Tree - 一种小巧高效的存树方式

该方法局限性较强,只在常数(不用递归)与码量上优于普通存图法,可以当看乐子。

无法树剖,唐完了。

0|1部分信息求解

我们定义 degu 表示节点 u 的度数,xru 表示 u 相邻的节点编号异或值。这里,我们令根节点的 deg 加一,以保证其根的地位。
我们从小到大 (1n) 遍历 u。当 degu=1 时,我们认为 xru 即为 u 的父亲节点,记作 f。这时,我们将 degfdegf1,degu0,xrfxrf xor u。若 degf=1,则向上遍历。代码如下:

++deg[1]; for (int i = 1; i <= n; ++i) { for (int x = i, y; deg[x] == 1; x = y) { y = xr[x]; --deg[y], deg[x] = 1, xr[y] ^= x; } }

结束后的 xr 即为树中的父亲数组。容易发现,很多信息也可以在遍历的过程中求解,如子树大小 sizu,最深深度 mxdepu。也存在无法遍历时求解的,如节点深度 depu,这类信息需要父亲节点的信息,可以倒着节点遍历顺序处理。

0|2dfs 序的求解

我们定义 dfnu 表示 u 节点的 dfs 序,difu 表示 u 节点与父节点 dfs 序的差值,即 dfnfaudfnu
这里还需要维护一个信息:u 节点子树大小 sizu
在上述删除 u 节点的过程中,我们做以下操作:

  1. sizusizu+1
  2. difusizxru+1
  3. sizxrusizxru+sizu
    对于节点 u,其所有祖先 dif 的和为其 dfn,按上述遍历顺序反向遍历即可。

0|3对边信息的解读

有些题目需要获得连向父亲的边,可以类似 xr 记录边编号的异或值,相似处理即可。

0|4效率比较

【模板】最近公共祖先(LCA)为例,图表如下:

实现方法 耗时 内存 链接
邻接表 2.65s 121.33MB here
链式前向星 1.82s 102.60MB here
Xor Tree 1.79s 86.48MB here

(这道题体现不出它的优势。。。)

1|0参考链接


__EOF__

本文作者TrueFalse
本文链接https://www.cnblogs.com/cqbzljh/p/18689347.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。您的鼓励是博主的最大动力!
posted @   cqbzljh  阅读(32)  评论(1编辑  收藏  举报
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现
点击右上角即可分享
微信分享提示