P9753 [CSP-S 2023] 消消乐
对于一个合法的串
- 一对字符
aa 是合法串; - 若
S 是合法串,则aSa 也是合法串; - 若
S,T 是合法串,则ST 也是合法串。
接下来我们将区分左括号的字符和右括号的字符。我们维护一个栈存所有当前的左括号的字符,但如果栈中有两个相邻的相同字符会很难受,所以我们要把这种情况调整掉。
具体而言,设有两个
所以可以得到合法串的判定:维护一个栈,若当前字符和栈顶相同就 pop,否则就 push,若最后栈可以删空即合法。
对于子串问题,我们断言,若
- 若
(l,r) 中还有其他位置栈形态与两端一致的,则分段处理,最后将每一段的串顺次拼接。 - 否则,考虑
l+1,r-1 的栈形态,我们断言其必须相同,否则:- 若
l+1,r-1 栈大小不一致,则中间必然有一个状态要返回和l,r 一样大小的栈,与假设矛盾; - 若
l+1,r 加入的字符不一致,则中间必然有一个状态要删除l+1 插入的字符,回到l 形态的栈,与假设矛盾。
- 若
- 即
l+1,r 必然同时删除,或加入相同的字符。
按照合法串定义,
还要证个方向,考虑按照定义递归易证。