人的一生不仅要靠自我奋斗,还要考虑到历史的行程。
历史的行程可以抽象成一个 串,作为一个年纪比较大的人,你希望从历史的行程中获得一些姿势。
你发现在历史的不同时刻,不断的有相同的事情发生。比如,有两个人同时在世纪之交 年的时候上台,同样喜欢与洋人谈笑风生,同样提出了以「三」字开头的理论。
你发现,一件事情可以看成是这个 串的一个前缀,这个前缀最右边的位置就是这个事情的结束时间。
两件事情的相似度可以看成,这两个前缀的最长公共后缀长度。
现在你很好奇,在一段区间内结束的事情中最相似的两件事情的相似度是多少呢?
Constraints
Solution
建出原串的 SAM ,则两个前缀的最长公共后缀为他们在 parent 树上的 lca ,问题转化为求区间内前缀两两 lca 深度的最大值。
将询问离线,按右端点从小到大排序。我们考虑每次加入一个字母,就将他们在 parent 树上到根节点的路径打上他们的标记。往根节点跑的过程中,若遇到了以前打的标记,则该节点为旧标记与新标记的 lca 。贪心可得应把标记尽量覆盖为较大的值。用树状数组来统计答案,下标为左端点,每次查询下标大于等于该询问左端点的最大深度。向根跑的过程中每一次遇到旧标记,就在树状数组上更新答案,并给该节点打上新标记。
往根节点跑的过程实际上就是 LCT 的 access 。
Code
1 |
|