后缀数组与马拉车学习笔记

后缀数组与马拉车学习笔记

串串这种细节特别多的比较弱啊,加练加练。

这篇学了 UKE 的标题编号方法看看会不会让观感更好

1 后缀数组

1.1 定义

后缀和子串这些基本定义就不放了吧(

  • 排名:字典序排名,空位补 \(0\)(注意这个 \(0\) 是 ASCll 的 \(0\) 而非字符 \(\text 0\))。

  • 后缀的下标:后缀的起始位置的下标。

  • \(sa_i\):所有后缀中排名为 \(i\) 的后缀的下标。

  • \(rk_i\):下标为 \(i\) 的后缀在所有后缀中的排名。

  • \(\text{lcp}(i,j)\):下标为 \(sa_i\)\(sa_j\) 的后缀的最长公共前缀的长度。

  • \(h(i)\)\(\text{lcp}(i,i-1)\)

1.2 实现

我们先考虑如何求 \(sa\)\(rk\)

首先有一个显然的性质:\(sa_{rk_i}=rk_{sa_i}=i\),这个实在是太显然了,我们考虑先求 \(sa\),然后用这个性质求 \(rk\)

我们发现对于两个长度为 \(2n\) 的字符串 \(s,t\)\(s>t\) 可以转化为 \(s[1,n]>t[1,n]\)\(s[1,n]=t[1,n]\)\(s[n+1,2n]>t[n+1,2n]\)

我们注意到这就是一个经典的二元组排序,只要将 \([1,n]\) 设为第一关键字,\([n+1,2n]\) 设为第二关键字排序后即可得到排名,而这两个关键字本身也可以分治求解,注意到这个东西的复杂度显然是 \(\log n\) 的,套上 sort 的 \(n\log n\) 就能 \(n\log^2n\) 解决,但是现在这个东西常数大而且本身复杂度劣,考虑优化。

我们现在的瓶颈显然是 sort,考虑将其换成基数排序,这里默认大家都会了,显然可以省去一个 \(\log\)

代码细节有点\(\huge 多\),但是我懒得贴代码了,读者加油吧(?)

然后是 \(h\)\(\text{lcp}\)

对于 \(h\),有这样一个性质:

\(h_{rk_i}\ge h_{rk_{i-1}}-1\)

证明:

\(h_{rk_{i-1}}\le1\) 时,上式显然成立。

否则因为 \(h_{rk_{i-1}}=\text {lcp}(sa_{rk_{i-1}},sa_{rk_{i-1}-1})\),注意到这里的 \(sa_{rk_{i-1}}=i-1\),我们设这里的 \(\text {lcp}\)\(\text{aA}\)(小写字母为字符,大写字母为字符串或空),后缀 \(i-1\)\(\text{aAD}\),后缀 \(sa_{rk_{i-1}-1}\)\(\text{aAB}\)

也就是说后缀 \(i\)\(\text{AD}\),后缀 \(sa_{rk_{i-1}-1}+1\)\(\text{AB}\)

而又因为 \(sa_{rk_{i}-1}\) 的排名只比 \(i(sa_{rk_{i}})\) 低一位,又有 \(\text{AB}<\text{AD}\),所以有 \(\text{AB}\le sa_{rk_{i}-1}< \text{AD}\) 也就是说 \(i\)\(sa_{rk_{i}-1}\) 有共同的前缀 \(\text A\)

于是 \(h_{rk_{i}}=\text{lcp}(sa_{rk_{i}},sa_{rk_{i}-1})=\text{lcp}(i,sa_{rk_{i}-1})\ge |A|=h_{rk_{i-1}}-1\),得证。

对于 \(\text{lcp}\),有以下几个性质:

  • \(\text{lcp}(i,j)=\text{lcp}(j,i)\)(显然)

  • \(\text{lcp}(i,i)=n-sa[i]+1\)(定义得)

  • \(\text{lcp}(i,j)=\min(\text{lcp}(i,k),\text{lcp}(k,j))(i\le k\le j)\)

    这个得证一下:

    \(\text {lcp}(i,j)=q\)\(\min(\text{lcp}(i,k),\text{lcp}(k,j))=p\)

    • 首先如果你是人类应该能看出 \(q\ge p\)

    • 接下来当 \(q>p\) 时显然有 \(q\ge p+1\),也就是说下标为 \(sa_i\) 的后缀和下标为 \(sa_j\) 的后缀中前 \(p+1\) 个字符都一样。

      但是因为 \(p\)\(\min(\text{lcp}(i,k),\text{lcp}(k,j))\),所以下标为 \(sa_k\) 的后缀的第 \(p+1\)至少和它们两个中一个的第 \(p+1\) 位不一样。

      而因为 \(i\le k\le j\),所以如果下标为 \(sa_j\) 和下标为 \(sa_i\) 的后缀的第 \(p+1\) 位一样而和下标为 \(sa_k\) 的后缀的第 \(p+1\) 位不一样那么它们两个的字典序中显然就不会夹着个 \(k\) 了,所以它们两个的第 \(p+1\) 位不一样,得出 \(q\le p\),从而有 \(q=p\)

  • \(\text{lcp}(i,j)=\min(h_k)\forall k\in i<k\le j\)(由上一条易扩展得)

1.3 例题

1.3.1 [JSOI2007] 字符加密

题目大意

原题晰。

题解

考虑把这个β循环断开,倍长字符串后跑板子即可。

1.3.2 [洛谷P2408] 不同子串个数

题目大意

原题晰。

题解

考虑正难则反,计算相同子串的数量后减去 \(\sum_{i=1}^nh_i\) 即可

1.3.3 [ural1297] Virtual Judge

题目大意

求一个字符串的最长回文子串。

题解

这个题怪显然的,把这个字符串倒着拼在它本身后面之后跑板子,然后这样匹配:

细节有点多,记得分类讨论奇数和偶数长度,中间还要有一个分界符比如 # 之类的。

1.3.4 [POI 2000] 公共串

题目大意

原题晰。

题解

先把所有串都拼到一起,然后考虑求出 \(h\) 后问题转化为找连续的一段使得至少每个串都出现一次,用一个长得很像莫队的双指针维护即可。

1.3.5 [USACO06DEC] Milk Patterns G

题目大意

求一个字符串中至少出现了 \(K\) 次的子串的最长长度。

题解

注意到以这种子串开头的后缀肯定是相邻的,所以问题转化为对于所有长度为 \(K-1\) 的子序列中 \(h\) 的最小值最大是多少,那单调队列或者随便啥数据结构瞎维护即可。

1.3.6 [SDOI2008] Sandy 的卡片

题目大意

公共串,但是如果一个串整体加或减后能匹配也算匹配。

题解

差分后跑 1.3.4 即可。(诶这个编号还真有用)

1.3.5 [SCOI2012] 喵星球上的点名

题目大意

原题晰。

题解

\(h\) 数组预处理后考虑按 \(sa\) 排序后预处理出能匹配到的姓/名,然后莫队瞎搞即可。

1.3.6 [AHOI2013] 差异

题目大意

原题晰。

题解

考虑求出所有 \(\text{lcp}\) 后用总长度 \(n\times(n+1)\times(n-1)\) 减,这就是一个显然的单调栈问题了。

1.3.7 [bzoj3230] 相似子串

题目大意

原题晰。

题解

细节\(\small{\huge\text巨}\)多的一道题啊。

自己手膜时也能发现的一个性质是一个后缀的前缀的排名是连续的,然后就这样去编号就可以了,接着二分找合法区间即可。

1.3.8 [NOI2015] 品酒大会

题目大意

原题晰。

题解

\(h\) 降序排序后一个插入,用并查集维护这个过程即可。

2 manacher

用于求解回文问题及其变种。

2.1 实现

我们首先规定对于一个回文串,它的中心就是 \(\lfloor\frac{l+r+1}{2}\rfloor\) (即偶数长度回文串中心是中间靠右)

接着设 \(d\) 为以 \(i\) 作为中心的奇数长度回文串的个数,只记录奇数的原因是这样处理而且对于一个字符串 \(\text{abacbab}\) 可以将其改为 \(\text{\#a\#b\#a\#c\#b\#a\#b\#}\),之后以 \(\text{\#}\) 为中心的回文串对应到原串上就是偶数长度的了。

我们动态维护最靠右的回文串,如果当前点在这个回文串内就可以直接从它的对应点开始扩展,否则就是它自己暴力扩展。

注意点最靠右回文串的右端点是不降的,所以复杂度线性。

2.2 例题

2.2.1 [POI 2010] ANT-Antisymmetry

题目大意

原题晰。

题解

把判断回文的条件改为不等即可。

2.2.2 神奇项链

题目大意

求最少用多少个回文子串可以完全覆盖原串。

题解

考虑贪心,维护 \(r_i\) 表示中心最右的能包含 \(i\) 的回文子串的中心,然后不断这样跳就行了。

2.2.3 [国家集训队] 拉拉队排练

题目大意

原题晰。

题解

\(d\) 搞到桶里,然后做后缀和用快速幂更新答案即可。

2.2.4 [ZJOI2009] 对称的正方形

题目大意

找到有多少个上下对称且左右对称的正方形。

题解

上下左右分别处理,用 ST 表维护能拓展长度的最小值,二分出最大的合法长度,统计答案时对上下拓展长和左右拓展长取 \(\min\) 即可。

posted @ 2025-06-04 18:03  LEWISAK  阅读(37)  评论(0)    收藏  举报