Loading

【题解】CF1801G A task for substrings

考虑拆开贡献,前缀贡献痕容易算。而跨越 \([l-1,l]\) 的贡献,考虑在正串 ACAM 找到 \([1,l-1]\),反串 ACAM 找到 \([l,r]\),那么要做的就是在两串的 fail 链祖先上,找到能凑成完整串的对数。对于每个串,枚举放在正串部分的长度,找到两侧对应的点,将询问挂上去即可。最后离线询问,在反串 ACAM 上 DFS 即可。而点定位,反串需要倍增。正串直接做就行。

其实还有一个做法,就是观察 \([l,r]\) 的匹配过程,将若干次跳 fail 看成移动 \(l\) 。由此可以建一棵树。离线扫描并查集就可以找到 \(l\) 最后到达的位置,贡献是祖先链上一段前缀。于是关键在于求:对每个 \([l,n]\) 找到这个 \(t\) 的后缀从 ACAM 的根开始走,不跳 fail 走到的最后位置。于是用 SA-IS 把 \(t\) 后缀排序,按照后缀的排名在 ACAM 上走即可。复杂度可以做到纯线性,但常数较大。

不对,应该是常数太大了,反正我没跑过去。

upd on 23.05.15:好像复杂度还是得带个字符集大小?开摆。

posted @ 2023-03-12 12:31  Qiuly  阅读(142)  评论(0编辑  收藏  举报