老Y的线段树 — 题解¶
Codex(GPT-6):本题的前驱倍增、持久化建模、证明、实现和验证;所用单调栈、倍增与持久化均为通用算法。
前一个严格更大的位置¶
令 \(prev[i]\) 为 \(i\) 左侧最近且值严格大于 \(a_i\) 的位置,不存在则为 \(0\) .用单调递减的下标栈预处理:读到 \(a_i\) 时弹出所有值不大于它的下标,剩余栈顶就是 \(prev[i]\) ,最后压入 \(i\) .每个位置只进出一次。
对区间 \([l,r]\) ,最后压入的 \(r\) 一定保留。它下面的元素是区间内最近的严格更大位置,即 \(prev[r]\) ,前提是该位置不小于 \(l\) .继续递推,最终栈正是从 \(r\) 沿 \(prev\) 向左走、尚未越过 \(l\) 的链,逆序读出。
倍增计数¶
预处理 \(up[j][i]=prev^{2^j}(i)\) .从 \(r\) 开始,计数为一;从大到小枚举层数,若跳 \(2^j\) 步后的位置仍不小于 \(l\) ,就跳过去并增加 \(2^j\) .链的下标严格减少,因此终点仍在区间内等价于整段跳跃均合法。所有可行大跳完成后,计数即链中点数。
按输入顺序用旧答案解码两个端点。数组为静态,倍增表与答案无关,可以提前建立;查询端点依赖旧答案,所以不能直接套用需要预先知道全部区间的离线排序。
正确性与复杂度¶
单调栈弹出的元素都不可能是当前点的严格更大前驱,而最后剩余栈顶是最近的合格位置,所以前驱表正确。链描述证明了查询等于合法前驱数量;倍增在严格递减链上恰好跨过所有仍在区间内的点,所以返回正确答案。逐次更新旧答案保证后续区间也被正确解码。
预处理 \(O(N\log N)\) ,每次查询 \(O(\log N)\) ,空间 \(O(N\log N)\) .Codex(GPT-6)提供规格补齐、算法推导、实现和验证,见 std.cpp。持久化方案 用前缀栈状态解释同一结构。