CF587F Duff is Mad
- 给定 \(n\) 个字符串 \(s_{1 \dots n}\)。
- \(q\) 次询问 \(s_{l \dots r}\) 在 \(s_k\) 中出现了多少次。
- \(n,q,\sum_{i=1}^n |s_i| \le 10^5\)。
字符串
根号分治
首先,建立 AC 自动机。
考虑暴力,就是将 \(s_{l\sim r}\) 的在 AC 自动机的终止节点的子树权值 +1,然后答案就是 \(s_k\) 在 AC 自动机上面对应路径的权值之和。
考虑差分之后扫描线,我们只要支持求将 \(s_{1 \sim cur}\) 的终止节点子树权值 \(+1\) 后,\(s_k\) 在 AC 自动机上面对应路径的权值之和了。
然后复杂度是 \(\mathcal O(\max\{|S_i|\} q \log_2 L)\) 的,其中 \(L = \sum |S_i|\)。
本来想使用树链剖分进行进一步优化的,但是因为 AC 自动机的路径在 Fail 树上不连续,因此我们只能暴跳然后求和。
但是我们可以根据字符串长度考虑根号分治。
具体地,对于 \(|s_k| \ge B\),我们可以将这些串对应的询问单独拿出来,然后将 \(s_k\) 在 AC 自动机上面对应的路径权值 +1,然后在对于每个 \(i\),求出如果 \(i \in [l, r]\),\(s_i\) 对于 \(s_k\) 的答案的贡献,这个只要在树上面 DFS 然后前缀和即可求解,总复杂度 \(\mathcal O(\frac{L^2}{B})\)。
对于 \(|s_k| < B\),直接使用暴力,总复杂度就是 \(\mathcal O(q B\log_2 L)\)。
根据均值不等式,当 \(B = \frac{L}{\sqrt{q\log_2 L}}\) 的时候复杂度最优,为 \(\mathcal O(L\sqrt{q\log_2 L})\)。
当然,如果第一部分写丑了直接树状数组多了个 \(\log_2\),那么也是可以调整块长然后通过的:代码。