[BJWC2018]Border 的四种求法(后缀自动机+链分治+线段树合并)
题目描述 给一个小写字母字符串 S ,q 次询问每次给出 l,r ,求 s[l..r] 的 Border 。 Border: 对于给定的串 s ,最大的 i 使得 s[1..i] = s[|s|-i+1..|s|], |s| 为 s 的长度。 题解 这题的描述很短,给人一种很可做的假象。 暴力1:每次对区间lr做一次KMP,求出border数组,复杂度nq。 暴力2:构建后缀自动机,用线段树合并维护出right集合考虑到两个串的最长后缀为他们在parent树上的LCA的len,所以我们可以在parent树上跳father,相当于枚举LCA,那么如果有匹配的点,则一定满足: i-len[LCA]+1<=l => i=len[LCA]<l => i<l+len[LCA] i>=l&&i<r (i为我们要求的点,l为询问的左端点,LCA为i和r的LCA) 所以我们只需要在线段树上查子树内查询满足上述条件的最大的i就可以了,复杂度最好qlogn,最差qn。 这两种暴力好像差不多。。 我们观察到第二种暴力它的瓶颈在于枚举LCA,但查询只需要一个log,我们可以想一些办法把复杂度均摊一下。 链分治 这就是这道题的重头戏,它用到了一个重要的性质,我们将一棵树重链剖分之后,从根到任意一点的路径上,轻重链切换的次数是不超过log的。 然后我们就可以用它搞一些事情。 比如说这道题