CF1340F Nastya and CBS

题意:你需要动态维护一个多种括号组成的,长度为 的括号序列。需要支持两种操作:

  • 单点修改

  • 查询 区间是否是一个合法的括号序列。

,时限 ,空限


先考虑如何暴力回答单组询问。

用栈维护括号序列的匹配。若出现左括号,加入栈中。若出现右括号,查看栈顶是否为同类,若是,则弹栈,若不是(或栈为空),失配。

分块

对于每个块内,跑一次括号匹配。

此处允许栈为空的情况,此时要将右括号加入栈中。

若匹配时内部已经出现了失配,则对该块打上标记。

若没有失配,最终剩下的括号形如 ,左边是一系列右括号,右边是一系列左括号。

回答询问时,将散块和整块的括号用栈再跑一次匹配。

先把散块按类似整块的方法整理。于是现在有若干段 “右右右左左左” 的括号序列等待合并。

这要求第 组的左括号与第 组的右括号完全匹配。使用 加速检验,复杂度可以做到

(兔队)线段树

对于每个线段树节点,维护内部匹配完之后剩下的括号,以及失配标记。

记左侧的右括号为 ,右侧的左括号为 。为了方便维护,我们可以将 翻转。

记要合并的两个点为 。考虑 ,不妨设 的长度较小,则将 抵消一部分,然后 剩余的一部分配上 为新的 ,原来的 即为

于是,我们在合并时需要查询 个位置的 值。

表示 长度为 的前缀的 值。

或者 可以直接返回结果。

否则,观察 是怎样得来的。

  • 这时 ,直接递归右儿子。

  • 这时

    ,直接递归左儿子。

    ,则查询 ,然后左侧加上

综上, 的复杂度为 ,每次操作的复杂度也就是 的。

询问时需要将拆分出的节点用栈记录,特殊写一个