Luogu6292 区间本质不同子串个数

题意:给出字符串 ,每次询问 的本质不同子串个数。

,时限


序列扫描线,逐渐增大右端点 ,并维护左端点 对应的询问 的答案。

考虑一个子串 能向询问 贡献的充要条件,不难想到选取最靠右的完整出现。具体地,右端点为 时, 中最后一次完整出现开头在 ,则需要满足 才能贡献。

维护一个数组 表示最后一次出现起点在 的串的个数。 的后缀和就是答案。


右移一位,会产生一个新的 endpos,这会更新从后缀点到根的路径,即所有后缀。这相当于先撤销所有后缀原来的贡献,再给 加一。

难点在于撤销贡献。对于一个 SAM 节点,将其“颜色”记为它最后出现的结束位置。对于某个节点,它的 是一段区间,结束位置一定,它对 (关注起始点)的影响也就是一段区间。

进一步地,parent tree 上一段相同颜色的点,其长度也是连续的,也只影响 的一个区间。它们可以用区间加法批量处理。

该过程非常像 LCT 的 access,于是在修改过程中,这样的段的个数均摊


当然,没必要真的写一个 LCT 来维护,有如下更初等的方法来模拟 access。

对于每种“颜色”,其在树上的出现位置形成一条链,起始点是叶节点,我们记录下终止点即最浅点。

若颜色编号递增,把颜色编号写在链起始的叶节点上,子树求 即可得知某个点当前的颜色。

每次断开某条链时,取用最浅点即可得到链顶,然后(由于断开了)把最浅点调整一下。

总复杂度