括号模型题的简单概括
((想)((不出)骚*)话了)
Prelude
合法括号串的定义如下:
-
()
是合法括号串。 - 如果
A
是合法括号串,则(A)
是合法括号串。 - 如果
A
,B
是合法括号串,则AB
是合法括号串。
XCPC 中经常会出现一些括号序列类的问题,这类问题在最开始的思考上一般是具有普遍共性的。常见的思考一般是:把 (
看成 $+1$,把 )
看成 $-1$。对于整个括号序列求前缀和 $p_i$,那么就有以下几条限制:
- $p_i \geq 0$,也就是不存在任意一个位置使得右括号的数量大于左括号的数量
- $|p_i - p_{i-1}| = 1$,这个显然。
然后通过这两个公式的转化,括号类问题又变成序列类问题,再上各种各样的算法去解决他们。当然还有一种比较经典的括号问题就是括号序列 DP。这个在下面的例题会讲到。以及最最传统的用栈去求一组合法匹配这种题。
例题1.[CSP-S2019] 括号树
一个大小为 $n$ 的树,树上结点从 $1 \sim n$ 编号,$1$ 号结点为树的根,$i$ 号结点的父亲为 $f_i$。
小 Q 发现这个树的每个结点上恰有一个括号,可能是
(
或)
。小 Q 定义 $s_i$ 为:将根结点到 $i$ 号结点的简单路径上的括号,按结点经过顺序依次排列组成的字符串。显然 $s_i$ 是个括号串,但不一定是合法括号串,因此现在小 Q 想对所有的 $i$($1\leq i\leq n$)求出,$s_i$ 中有多少个互不相同的子串是合法括号串。
$n \leq 5\times 10^5$
这个题其实是一个树形 DP 题,但是因为和括号结合起来了看着有点变态。思考一下,我们现在考虑 $s_i$ 从哪里来,显然考虑 $[1,i]$ 这一段的括号序列实际上是可以由 $[1,f_i] $ 转移过来的。我们可以用 $s_i$ 这一位的括号来匹配掉之前存在的括号,以此产生新的子串。
难点在于维护新增子串这里,具体来说,我们需要像做一个最普通的子串匹配一样,用一个栈 $st[x]$ 来保存到节点 $x$ 的匹配情况,接下来我们讨论一下:
- $s_i = ($ ,这里显然不会和之前的新增任何子串,影响为 0.
- $s_i = )$,这里还有两种讨论方法,
- 若栈为空,那么显然没有任何讨论价值。
- 若栈非空且栈顶可以匹配,我们可以写出递推式 $dp_x = dp[f[st[top]] + 1$,这个递推式的含义是考虑从匹配那个点的转移过来。
1 |
|
例题2.[CSP-S 2021] 括号序列
小 w 在赛场上遇到了这样一个题:一个长度为 $n$ 且符合规范的括号序列,其有些位置已经确定了,有些位置尚未确定,求这样的括号序列一共有多少个。
身经百战的小 w 当然一眼就秒了这题,不仅如此,他还觉得一场正式比赛出这么简单的模板题也太小儿科了,于是他把这题进行了加强之后顺手扔给了小 c。
具体而言,小 w 定义“超级括号序列”是由字符
(
、)
、*
组成的字符串,并且对于某个给定的常数 $k$,给出了“符合规范的超级括号序列”的定义如下:
()
、(S)
均是符合规范的超级括号序列,其中S
表示任意一个仅由不超过 $k$ 个字符*
组成的非空字符串(以下两条规则中的S
均为此含义);- 如果字符串
A
和B
均为符合规范的超级括号序列,那么字符串AB
、ASB
均为符合规范的超级括号序列,其中AB
表示把字符串A
和字符串B
拼接在一起形成的字符串;- 如果字符串
A
为符合规范的超级括号序列,那么字符串(A)
、(SA)
、(AS)
均为符合规范的超级括号序列。- 所有符合规范的超级括号序列均可通过上述 3 条规则得到。
例如,若 $k = 3$,则字符串
((**()*(*))*)(***)
是符合规范的超级括号序列,但字符串*()
、(*()*)
、((**))*)
、(****(*))
均不是。特别地,空字符串也不被视为符合规范的超级括号序列。现在给出一个长度为 $n$ 的超级括号序列,其中有一些位置的字符已经确定,另外一些位置的字符尚未确定(用
?
表示)。小 w 希望能计算出:有多少种将所有尚未确定的字符一一确定的方法,使得得到的字符串是一个符合规范的超级括号序列?$1 \le k \le n \le 500$。
神人题,但是也很经典。本质上这种括号序列 + DP 的题都是要把答案的形态考虑明白,然后再进行转移。
我们考虑以下几种答案状态:
(...)
左右端自我匹配,这种记为 $f_{i,j}$(...)...(...)
左右端匹配,但是这俩本身并不匹配,这种记为 $g_{i,j}$(SA)
这种单独讨论一下,主要问题是判断S
,这种记为 $SA_{i,j}$,然后(AS)
本质上也是一样的,其实这两种都可以规约到 $f$ 里面,就是转移的时候需要注意一下。ASB
和AB
需要特别注意,当然这两种还是很简单的。
具体方程讨论太长了有点懒得敲,还是直接看 code:
1 |
|
例题3.SHCPC2022 Bracket Query
我承认是为了这碟醋才包这碟饺子的
这个题就是特别经典的利用前缀和转化了,题目给的条件实际上可以转化为 $p_r - p_{l-1} = x$,那么这个条件有一个好,就是特别方便建出差分约束的图(当然使用带权并查集也可以)
求出差分约束之后,我们知道因为一组差分约束的序列 $X$ 可以同时加上偏移量 $\Delta$ 从而使得同样成立,我们实际上求出来一组合法解之后调整一下,根据 $p_i - p{i-1}$ 的正负性来判断就 OK,这样构造出的序列就是合法。如果图里有负环就倒闭了。
注意到我们还有 $|p_i - p_{i-1}| = 1$ 这个条件,经过这个条件的约束下,我们去做 SLF 优化的 SPFA,那么实际上复杂度和 01 BFS 等价,是 $O(n+m)$ 的,所以很稳健啊兄弟们(手动 at Qzong)
1 | /* |
例题4.Rainbow Bracket Sequence
括号序列匹配+最优化问题+一系列限制条件+较小的数据范围=最小费用最大流模型
赛时想到过上下界,但是因为不会这个东西就没继续往下想。
不过其实我们有本质更简单的做法,即先假设所有位置都填了左括号,此时需要选出 nn 个位置将其变为右括号
用经典 trick,合法括号序列的充要条件为:
- 后 $2i−1$ 个位置中至少要有 $i$ 个右括号;
- 最后 $2n$ 个位置中恰好要有 $n$ 个右括号;
同时由于我们预设了每个位置都填左括号,则下界的要求初始时一定是满足的(特判掉显然无解的情况后)
此时每个颜色就有了一个将左括号转为右括号数的上界,此时就可以用传统的费用流模型来处理了
将每个颜色拆出一个虚点,并求出每个颜色 $j$ 最多只能转化的右括号个数 $lim_j$
- $S$ 向 $2n$ 连 $(n,0)$ 的边;
- 点 $i+1$ 向点 $i$ 连 $(⌊\frac{i}{2}⌋,0)$ 的边;
- 点 $i$ 向点 $n+c_i$ 连 $(1,v_i)$ 的边;
- 点 $n+j$ 向 $T$ 连 $(lim_j,0)$ 的边;
最后用 $∑v_i$ 减去该图的最小费用最大流即可
1 | /* |
括号模型题的简单概括