给串$A$和$B$,求有多少组$(la,ra,lb,rb)$,使得$A[la..ra] = B[lb..rb]$。
day3
$O(n^2)$
如果能够满足$O(n^2)$的算法,可以用以下方法做。
字符串hash + map
先对A和B进行hash预处理。
首先枚举相同子串长度len,遍历A的所有长度为len的子串,得到hash值,并且用map进行记录个数。
然后再到B串里进行相应统计便可。整体复杂度是$O(n^2logn)$的。
1 |
|
后缀数组
首先对$S=A+dollor+B$的字符串进行后缀排序,处理出height数组。
我们知道$lcp(suf_i,suf_j) = min(height[i+1],height[i+2]..height[j]) $。
假如$suf_i$是A串的后缀,那么从$i+1$开始遍历,并维护$lcp$便可求出$suf_i$对答案的贡献。
需要枚举$i$和遍历$i$之后的所有后缀,$lcp$可以$O(1)$维护,复杂度$O(n^2)$。
1 |
|
$O(n)$
后缀数组+单调栈
前文提到的后缀数组方法有一个硬伤,就是需要枚举每一个后缀,能不能只用一次循环就维护出贡献呢?这里可以运用前缀和的思想以及单调栈来维护。
由于存在性质:$lcp(suf_i,suf_j) = min(height[i+1],height[i+2]..height[j]) $,所以对于$suf_i$而言,每个$suf_j$的贡献是越来越小的,也就是说满足单调性。
那么考虑如何维护这个前缀和。假设栈内当前每个后缀贡献长度为$a$,此时对于$suf_j$,贡献为$min(height[j],a)$。如果$height[j] \lt a$,前面所有的后缀贡献都会被更新为$height[j]$,否则,分开算贡献即可。
复杂度分析:$O(nlogn)$的预处理和$O(n)$的求值,整体$O(nlogn)$。
1 |
|
后缀自动机+DP
留坑。