1 条题解

  • 0
    @ 2026-8-20 15:10:30

    题解

    思路推导

    把每条树边标记为它连接的儿子在兄弟节点中的编号排名。于是,从根到任意节点的路径都对应一个唯一的正整数序列。一次询问从节点 xx 出发,依次使用 al,al+1,,ara_l,a_{l+1},\ldots,a_r,等价于把这段序列接在根到 xx 的路径序列之后,并寻找仍然对应树中节点的最长前缀。

    将序列按多项式方式哈希。预处理根到每个节点的路径哈希,并以“深度与哈希值”为键保存对应节点。由于树中一条边序列至多对应一个节点,只要拼接后的键存在,就说明整段移动可以完成;否则必须在这一段内部寻找第一个无法继续的位置。

    哈希使用两个不同质数模数同时计算。算法的逻辑判定依赖两个哈希同时相等;双模用于把碰撞风险降到极低。独立核验程序使用不同的六十四位哈希实现,正式小规模数据还由逐步模拟验证。

    做法

    对子任务 1,直接保存每个节点按编号升序排列的儿子。每次询问逐个读取区间中的 aia_i,若排名存在就进入对应儿子,否则停止。修改操作直接修改数组。

    对子任务 2,没有修改操作。用前缀哈希在常数时间取得任意子区间的规范化哈希,再二分能够完整走过的最长前缀长度。每次判定把该前缀接到根至 xx 的路径哈希后,在预处理的节点映射中查询。

    满分做法用线段树维护序列哈希。每个线段树节点保存区间长度以及从零次幂开始的区间哈希,左右儿子的哈希可以直接拼接;单点修改沿祖先链重新计算。

    处理询问区间时从左到右访问线段树。若当前已经确认的路径拼接整个线段树节点后仍能在树中找到对应节点,就一次接受整个区间并继续;否则向该线段树节点的两个儿子递归。第一次到达不能接受的叶子时停止,当前记录的节点就是答案。区间分解只经过对数个完整节点,并且至多沿一条失败路径继续下降,因此一次询问的复杂度为对数级。

    正确性说明

    根到节点的边排名序列是唯一的。询问执行若干步后到达节点 yy,当且仅当“根到 xx 的排名序列”与“已经读取的询问序列前缀”的拼接等于根到 yy 的排名序列。

    线段树处理始终维护已经确认可以完成的最长前缀及其终点。若拼接一个完整区间后能在节点映射中找到对应深度与哈希,整个区间都对应一条真实树路径,可以安全接受。若找不到,则完整区间不可能全部走完;递归到左右子区间会保持从左到右的顺序,并最终定位第一项无法继续的位置。因此停止时维护的前缀恰为最大合法前缀,记录节点也恰为题目要求的停留节点。

    复杂度分析

    预处理树路径与建立线段树需要 O(n+m)O(n+m) 时间和 O(n+m)O(n+m) 空间。每次修改和询问均为 O(logm)O(\log m) 时间。子任务 2 的静态前缀哈希做法每次询问为 O(logm)O(\log m),子任务 1 的直接模拟为 O(rl+1)O(r-l+1)

    • 1

    信息

    ID
    928
    时间
    3000ms
    内存
    256MiB
    难度
    10
    标签
    递交数
    1
    已通过
    0
    上传者