题意:
给定字符串 \(S,T,P\),求将 \(T\) 插入进 \(S\) 之后 \(P\) 最多的出现次数。输出:
- 最多的出现次数;
- 达到这个最多出现次数的插入位置数量;
- 达到这个最多出现次数的最靠前的插入位置;
- 达到这个最多出现次数的最靠后的插入位置。
数据范围:\(1\le |S|,|T|,|P|\le 10^5\)。
题目要我们求的信息量很大,不妨直接求出在每个位置插入 \(T\) 之后 \(P\) 的出现次数。
设将 \(T\) 插入之后 \(S\) 前后两部分为 \(A,B\)。
讨论 \(P\) 出现的位置情况:
- 完全包含于 \(T/A/B\):可以直接 KMP 预处理。
- \(A+T\):求出所有长度 \(x\) 满足 \(T\) 长度为 \(x\) 的前缀和 \(P\) 长度为 \(x\) 的后缀匹配。建出 \(S\) 匹配 \(P\) 的失配树,把所有编号为 \(x-1\) 的节点打上标记,在 \(i\) 后插入 \(T\) 得到的形如 \(A+T\) 的匹配数量就相当于失配树上 \(S_{1,i}\) 匹配 \(P\) 的最长前缀的所有祖先的标记和。
- \(T+B\):将 \(S\)、\(T\)、\(P\) 全部翻转,再做一遍 \(A+T\) 的过程。
- \(A+T+B\):求出所有 \(T\) 在 \(P\) 中的匹配位置 \([x+1,x+|T|]\),然后就相当于统计有多少位置 \(i\) 满足 \(S_{i-x+1,i}=P_{1,x}\) 且 \(S_{i+1,i+|P|-|T|}=P_{x+|T|+1,|P|}\)。求出 \(S_{1,i}\) 匹配 \(P\) 的最长前缀长度和 \(S_{i+1,|S|}\) 匹配 \(P\) 的反串的最长匹配长度,设为 \(u,v\),那么就是问有多少个 \(x\) 满足 \(x\) 在正串失配树上是 \(u\) 的祖先且 \(|P|-x-|T|\) 在反串失配树上是 \(v\) 的祖先。这是一个二维数点问题,可以离线扫描线 + 树状数组完成。
注意树状数组上界要开到 \(|P|+1\)……因为节点数是最大编号 \(+1\)……
代码:https://paste.ubuntu.com/p/xnd9gHx5WD/。
标签:位置,匹配,次数,题解,CERC2022,插入,QOJ5256,长度,失配 From: https://www.cnblogs.com/xsl19/p/cerc2022-h-sol.html