UVA10829 L-Gap Substrings

我永远喜欢数据结构。

貌似是此题中第一个使用 SA + 分治 + 二维数点做法的题解?

题目传送门

  • 给出字符串 \(s\) 和常数 \(g\),求出有多少四元组 \((l_1,r_1,l_2,r_2)\),满足 \(s[l_1,r_1]=s[l_2,r_2]\)\(r_1+g+1=l_2\)

  • \(T\) 组数据,\(1\le T,g\le 10\)\(|s|\le 5\times 10^4\)

不知道 \(1\le g\le10\) 有啥用。

先后缀排序。

考虑一对合法的 \(s[l_1,r_1]\)\(s[l_2,r_2]\) 来自分别哪个后缀。假设它们分别来自排名\(i\)\(j\) 的后缀(显然 \(\text{sa}_i=l_1,\text{sa}_j=l_2\))。令 \(u=\min\{i,j\},v=\max\{i,j\}\),此时 \(u<v\)。则一定满足,\(|\text{LCP}(s[\text{sa}_u,|s|],s[\text{sa}_v,|s|])|\ge |\text{sa}_u-\text{sa}_v|-g\)。因为它们已经有了 \(r_1-l_1+1\) 这个长度的最长公共前缀。这种情况下我们称 \((l_1,r_1,l_2,r_2)\) 这个四元组与 \((u,v)\) 这个二元组对应。对于同一对 \((l_1,r_1,l_2,r_2)\),由于 \(l_1,l_2\) 都是确定的,所以它只会与唯一一对 \((u,v)\) 对应。

我们再考虑对于一个 \((u,v)(u<v)\) 的二元组,若满足 \(|\text{LCP}(s[\text{sa}_u,|s|],s[\text{sa}_v,|s|])|\ge |\text{sa}_u-\text{sa}_v|-g\),此时令 \(i=\min\{\text{sa}_u,\text{sa}_v\},j=\max\{\text{sa}_u,\text{sa}_v\}\),则 \((i,j-k-1,j,2j-k-i-1)\) 一定是一个合法的四元组。我们让它们对应。则一个对于二元组 \((u,v)\),它们已经确定了两个串的起点,则终点也随之确定了,所以对应了唯一一个合法的四元组。

我们发现合法的二元组与合法的四元组一一对应。

那么只需要统计有多少满足条件的 \((u,v)(u<v)\),任意一个合法的四元组都会在与之对应的二元组处被统计一次后就不再统计,且任意一个合法的二元组统计的都是与之对应的一个合法的四元组,做到了不多、不重、不漏。

考虑转化成 \(\text{height}\) 数组的限制,则要统计满足一下条件的 \((u,v)\) 个数:

\[\begin{cases}u<v\\|\text{sa}_u-\text{sa}_v|-g\le \min\limits_{i=u+1}^v\text{height}_i\end{cases} \]

套路地分治,设当且分治区间为 \([l,r]\),中点 \(\text{mid}=\left\lfloor\dfrac{l+r}{2}\right\rfloor\)。考虑统计跨过 \(\text{mid}\) 的贡献。考虑固定 \(u\)

\(\text{mid}\rightarrow l\) 扫描 \(u\),处理 \(\text{mn}=\min\limits_{i=u+1}^{\text{mid}}\text{height}_i\),设 \(\text{pre}_v=\min\limits_{j=\text {mid}+1}^v \text{height}_j\),钦定 \(\text{pre}_{r+1}\) 极小。此时 \(\text{pre}\) 是不升的。则一定存在一个 \(p\in[\text{mid+1},r+1]\) 使得 \(\text{pre}_p<\text{mn}\)。这种情况下,当 \(v\in[\text{mid}+1,p)\)\(\min\limits_{i=u+1}^v\text{height}_i=\text{mn}\);当 \(v\in[p,r]\)\(\min\limits_{i=u+1}^v\text{height}_i=\text{pre}_v\)

对于 \(v\in[\text{mid}+1,p)\) 的部分,就是要统计有多少 \(v\) 满足 \(|\text{sa}_u-\text{sa}_v|-g\le \text{mn}\)。拆绝对值后二维数点即可。

对于 \(v\in[p,r]\) 的部分,就是要统计有多少 \(v\) 满足 \(|\text{sa}_u-\text{sa}_v|-g\le \text{pre}_v\)。同样拆绝对值,但是你发现此时变成三维数点,不能接受。

考虑一个智慧的容斥,对于 \(v\in[p,r]\) 的部分,先统计有多少 \(v\) 满足 \(|\text{sa}_u-\text{sa}_v|-g\le \text{mn}\),然后对于 \(\text{pre}_v<|\text{sa}_u-\text{sa}_v|-g\le \text{mn}\)\(v\) 减去它们的贡献。

由于对于 \(v\in[\text{mid}+1,p)\) 的部分 \(\text{pre}_v\ge \text{mn}\),所以我们只需要减去全局 \(\text{pre}_v<|\text{sa}_u-\text{sa}_v|-g\le \text{mn}\)\(v\) 的贡献。这样少了一个 \(v\) 的限制,拆绝对值后仍是二维数点,离线 + BIT 解决。

此时,两部分 \(|\text{sa}_u-\text{sa}_v|-g\le \text{mn}\) 的贡献都要计算,于是全局维护一个 \(\text{sa}_v\) 的值域 BIT 即可。

注意这里拆绝对值和解不等式的细节,尤其是不能忽略 \(\text{sa}_v\in[1,|s|]\) 的这个先天限制。

然后往两半递归求解即可。

这题就做完了,时间复杂度为 \(\mathcal{O}\left(|s|\log^2|s|\right)\),空间复杂度为 \(\mathcal{O}(|s|)\)。代码不算很难写。

AC Link

AC Code

posted @ 2024-03-17 10:45  蒟蒻·廖子阳  阅读(4)  评论(0编辑  收藏  举报