DTOJ #3194. 去月球 题解
作者:互联网
几个关键点。
- 可以用栈模拟求答案过程,因为随便匹配答案也是对的,很好反证,读者自证不难。
- 对于区间 \([l,r]\) 询问,可以用前缀 \(l-1\) 和前缀 \(r\) 的栈状态回答:如果 \(l-1\) 的状态是 \(a_1,a_2,\dots,a_x\),加入 \([l,r]\) 后,变成 \(a_1,a_2,\dots,a_y\),其中两段的 \(\operatorname{lcp}\) 为 \(a_1,a_2,\dots,a_k\)。区间 \([l,r]\) 内无法匹配的数量即为 \(x+y-2k\)。证明如下:
- 如果区间 \([l,r]\) 中的一段完美匹配没有被用来配对 \(l-1\) 的栈,那么这段完美匹配不会被用来贡献答案,理由显然,因为这一段完美匹配根本不会影响 \(l-1\) 的栈状态。
- 如果区间 \([l,r]\) 中的一段完美匹配的部分被用来配对 \(l-1\) 的栈,会发现这一段仍然不会修改 \(l-1\) 的栈状态。因为如果完美匹配的其中一个左括号用来匹配 \(l-1\),右括号就一定会填回原来的位置。
- 发现无法存下每个前缀栈状态,考虑按顺序加点,用 trie 来存储,类似主席树。因为入栈元素和出栈元素在 trie 上都可以很好地找到对应的操作(走儿子,跳父亲),在 trie 上查询 \(\operatorname{lcp}\) 就相当于查询 \(\operatorname{lca}\)。
- 顺带一提,这个存前缀
(似乎)实现了可持久化栈。
标签:dots,匹配,前缀,完美,题解,trie,3194,DTOJ,operatorname 来源: https://www.cnblogs.com/lingfunny/p/16364730.html