后缀数组

后缀数组

sai 表示排名为 i 的后缀为 S[sai,n]rki 表示 S[i,n] 的排名,即后缀数组(Suffix Array)。不难得到:

sarki=rksai=i

倍增求解

P3809 【模板】后缀排序

考虑已经将每个串以前 2k1 个字符为关键字排好序,接下来需要以前 2k 个字符为关键字排好序。

由于 2k=2k1+2k1 ,于是只要做一次双关键字排序即可。其中第一关键字为 S[i,i+2k11] ,第二关键字为 S[i+2k1,i+2k1] ,这两个信息的大小比较在上一轮排序中均可找到。

一些优化:

  • 当倍增数量大于字符串数量时,就可以停止倍增。

  • 并且当所有 sai 都不相同时,就可以停止排序。

使用计数排序可以做到 O(nlogn)

LCP 相关

lcp(i,j)=LCP(S[sai,n],S[saj,n]),hti=lcp(i1,i) ,则有:

  • LCP Lemma:1i<j<kn,lcp(i,k)=min(lcp(i,j),lcp(j,k))
  • LCP Theorem:ii<jn,lcp(i,j)=mink=i+1jhtk
  • LCP Corollary:1ij<kn,lcp(i,j)lcp(i,k)

于是求解两个后缀的 LCP 可以转化为 ht 数组上的 RMQ 问题。

hi=htrki ,则:

hihi11

证明:在 sa 数组里面找一个后缀,设它在原字符串的下标为 i1 ,前一个后缀在原字符串的下标为 k 。把它们两个后缀的首字母都砍掉,它们就变成了 ik+1

当两个字符串首字母不同时,它们的 LCP 就是 0 。否则删除首字母后排名先后肯定也是不变的,且它们的 LCP 长度为 hi11 。而由 LCP Lemma 可知,这个 LCP 长度是这个区间中最小的。因此 hihi11

用指针维护 hi 可以线性求出 ht

应用

P2408 不同子串个数

求长为 n 的字符串的不同子串个数。

n105

发现每个子串都是一个后缀的前缀,考虑在排名最小的后缀处统计贡献。那么多出来的部分就是排名相邻的两个后缀的 LCP ,答案即为 n(n+1)2i=2nhti

SP1811 LCS - Longest Common Substring

求两个串的最长公共子串。

n2.5×105

把两个串拼起来,中间塞一个无关字符,答案即为 height 数组的最大值(需要保证前后两个后缀串分别来自给出的两个串)。

P3181 [HAOI2016] 找相同字符

给定两个字符串,求出在两个字符串中各取出一个子串使得这两个子串相同的方案数。两个方案不同当且仅当这两个子串中有一个位置不同。

n2×105

本质上就是算所有后缀两两之间的 LCP 和,但是需要来自两个不同串。考虑把两个串拼起来(中间塞一个无关字符)做一次,然后再减去两个串分别做一次的贡献。问题转化为 ht 数组上所有子区间的最小值之和,不难用单调栈解决。

P4248 [AHOI2013] 差异

求:1i<jn|S[i,n]|+|S[j,n]|2×lcp(S[i,n],S[j,n])

n5×105

前半部分总和为 n(n1)(n+1)2 ,后半部分和上题一样。

P4094 [HEOI2016/TJOI2016] 字符串

给定字符串, m 次询问 S[a,b] 所有子串与 S[c,d] 的 LCP 最大值。

n,m105

考虑二分答案,那么对于 LCPmid 的限制可以对 ht 建立 ST 表后二分求出一段后缀排名的区间,S[a,b] 的限制可以转化为一段下标的区间。静态二维数点用主席树解决即可,时间复杂度 O(nlog2n)

P2178 [NOI2015] 品酒大会

给定长度为 n 的字符串与权值 a1n 。对于所有 i[1,n] ,求有多少对后缀满足 LCP 长度 i 以及满足条件的两个后缀权值乘积的最大值。

n3×105

考虑倒序枚举 i ,则每次都会将 ht=i 的位置的两个后缀合并为一个连通块,两个问题的答案都可以通过并查集维护连通块来处理,时间复杂度 O(nlogn)

P5284 [十二省联考 2019] 字符串问题

现有一个字符串 S ,从中划出 na 个子串作为 A 类串,再划出 nb 个子串作为 B 类串。

额外给定 m 组支配关系,每组支配关系 (x,y) 表示第 x 个 A 类串支配第 y 个 B 类串。

求长度最大的串 T 长度,满足存在一个串 T 的分割 T=t1+t2++tk 满足:

  • 分割中的每个串 ti 均为 A 类串。
  • 对于分割中所有相邻的串 ti,ti+1 ,都存在一个 ti 支配的 B 类串为 ti+1 的前缀。

特别地,若存在无限长的 T ,输出 1

|S|,na,nb2×105

题目转化为:给定一些从 A 类区间连向 B 类区间的边,一个 B 区间能连向一个 A 区间当且仅当前者是后者的前缀。求这张图上的最长路(或判断无限长)。

显然若有环则答案可以无限大,否则直接在 DAG 上 DP 即可。

考虑优化 B 区间到 A 区间的边,发现包含某个 B 串作为前缀的 A 串需要满足两个条件:

  • 以二者左端点开始的后缀的 LCP 长度不小于 B 串长度:转化为对应着后缀数组上的一段区间。
  • A 串长度不小于 B 串长度:按照长度从大到小的顺序加入每个串即可。

使用主席树优化建图,时间复杂度 O((n+na+nb)logn)

相似子串

定义字符串 A 与字符串 B 相似当且仅当 Ai=AjBi=Bj

给定长度为 n 的数字串 Sq 次询问与某个子串相似的子串数量,强制在线。

n105q5×105

考虑对于一个子串,每个位置的权值定义为与上一个相同字符的下标差,若在该子串中首次出现则为 0 ,则两个字符串相似当且仅当它们每个位置的权值相同。

首先对原权值构建出 ht 数组,然后可以注意到截取一段子串时,最多只会有 10 个位置变为 0 ,那么二分时分段比较即可,

P4070 [SDOI2016] 生成魔咒

给定 a1n ,求每个前缀本质不同子串数量。

n105

若直接求解,每次在末尾加数字时,ht 数组的变化是难以维护的。

考虑将字符串反转,则每次相当于在前面加一个数字,相当于加入一个前缀,对 ht 数组的影响是 O(1) 的。

使用 set 维护前驱后继,时间复杂度 O(nlogn)

P1117 [NOI2016] 优秀的拆分

给出字符串 S ,求有多少形如 AABB 的子串,其中 A,B 为字符串。

n3×104

fi 表示以 i 结尾的 AA 串数量,gi 表示以 i 开头的 BB 串数量,则答案为 fi×gi+1

考虑枚举 A 串的长度 len ,统计所有长度为 lenA 串贡献。称下标为 len 倍数的位置为关键点,则任意一个 AA 串都覆盖相邻关键点,于是可以枚举相邻的关键点统计。

对于相邻的关键点 i,i+len ,若被一个 AA 串覆盖,则这个 AA 串去掉中间 ii+len 的部分后必须是 A 串。

设这个 AA 串的分界点为 k ,那么 ik 应该与 i+len 开始的一段后缀相等,k+1i+len 应该与 i 结尾的一段前缀相等。

因此若两个后缀 i,i+len 的最长公共前缀 l1 与两个前缀 i1,i+len1 的最长公共后缀 l2 的和 len ,则存在 l!+l2len+1AA 串覆盖 i,i+len 。注意 l1 要对 lenminl2 要对 len1min

不难发现这是一个区间加一的形式,使用差分即可。求两个后缀的最长公共前缀和求两个前缀的最长公共后缀可以对正反串各建出 SA 解决。

时间复杂度 O(nlogn)

P5115 Check,Check,Check one two!

给定一个长为 n 的字符串 S ,定义:

  • lcp(i,j)S[i,n]S[j,n] 的最长公共前缀。
  • lcs(i,j)S[1,i]S[1,j] 的最长公共后缀。

求:

(1i<jn[lcp(i,j)k1][lcs(i,j)k2]×lcp(i,j)×lcs(i,j))mod264

n105

发现 lcs(i,j)lcp(i,j) 拼起来就是一个长为 lcs(i,j)+lcp(i,j)1 的极长公共子串,考虑在 (ilcs(i,j)+1,jlcs(i,j)+1) 处统计贡献。

枚举 i,j ,若 Si1Sj1 ,则 S[i,i+lcp(i,j)1] 产生贡献。进一步可以发现贡献仅与 L=lcp(i,j) 有关,记:

(1)f(L)=i=1Li×(Li+1)[ik1][ni+1k2](2)=nk2+1k1(L+1)×ii2

不难 O(n) 预处理 f(1n)

但是 Si1Sj1 的位置还是很多,考虑容斥,用无限制的答案减去 Si1=Sj1 的答案即可。剩下的根据 lcp 即为区间 ht 最小值的性质,对 ht 数组做扫描线,维护单调栈即可。

时间复杂度 O(nlogn)

CF653F Paper task

给出一个长度为 n 的括号串,求本质不同的合法括号串数量。

n5×105

先不考虑本质不同的限制,将左右括号记为 1,1 ,记 si 为前缀和,则 S[l,r] 合法当且仅当 [sr=sl1][sl1mini=lrsi]

对于一个 l ,可以二分出满足 sl1mini=lrsi 的最大右端点,则合法的右端点只要对 s 的每个值记录位置然后二分查找即可。

接下来考虑本质不同的限制,后缀排序后只要对减去排名相邻的两个串的公共合法前缀数量即可,求法是类似的。

时间复杂度 O(nlogn)

posted @   wshcl  阅读(10)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】
点击右上角即可分享
微信分享提示