于是, 在栈底部的下面还需要分配一个保留位置, 用于记录与另半条路径匹配的竖线数量. 每次遇到右括号, 如果栈顶是保留位置, 则将其压入用于记录匹配信息的序列, 并清零保留位置. 这样, 每个点 y 都记录了一正一反两个序列表示匹配信息, 其中每个元素表示独属于从 x 往 y 方向第 i 个未匹配的右括号的竖线数量. 那么显然, 一个正序列和一个反序列能匹配成功, 当且仅当它们长度相等且对应位置之和都为 k.
类似算法三对每个点记录正反两个序列. 不同的是, k 是任意的, 那么就不能在半条路径内部匹配时检查竖线数量是否为 k. 不过我们知道, 如果两次匹配得到的竖线数量不同, 那肯定不合法, 这就是说, k 要么是任意的, 要么是唯一的. 我们对每个点的正反两个方向再记录一个数, 如果其等于 -1 则表示 k 任意, 否则表示唯一的那个 k.
另一个不同是, 现在只知道两个序列能匹配成功仅当长度相等且对应位置之和都相等. 这可以对差分哈希, 从而划分出等价类. 每个等价类中, k 唯一的那些可以类似算法三直接查询然后贡献答案, 这样简单处理掉, 不再赘述. 以下假设所有都是 k 任意.
那么对于同一等价类里的任意一对正反序列, 它们都能贡献答案, 特殊地, 设其第一个元素分别是 x, y, 则贡献到 k = x + y. 这等价于一个卷积. 对每个等价类做卷积显然不现实, 不过我们注意到以 x 为重心时, 参与卷积的非零元素只有 \mathrm O(s) 个, 其中 s 是当前连通块大小. 那么可以根号分治, 令 B = \mathrm O(\sqrt{s \log s}), 对非零元素数量不超过 B 的等价类暴力, 否则 NTT, 这样两部分的复杂度都是 \mathrm O(s\sqrt{s \log s}), 达到平衡. 根据 Master 定理, 外面套一层点分治后, 总时间复杂度是 \mathrm O(n \sqrt{n \log n}), 可以通过 Subtask 1, 5, 期望得分 30 分到 100 分.