后缀数组
一些后缀数组的应用。
标 \(^*\) 的题目是我还没有做,但是存在 SA 做法的题。
其实这篇名为学习笔记的东西更像一个题单。
1.利用 \(sa\) 和 \(rk\) 数组
这类题目通常需要发掘一些性质,转化为 求串的字典序最小/大后缀或长度固定的子串。
P3809 【模板】后缀排序
后缀数组板子。
P4051 字符加密
求出 \(sa\) 数组即可。
P6095 [JSOI2015] 串分割
二分答案串的排名。
CF1923F Shrink-Reverse
转化为求长度为 \(len\) 的字典序最小子串。
AT_ddcc2020_final_c Smaller-Suffix-Free Sequences
找到 Lyndon 串的性质,转化题意。
2.本质不同子串
这类题目的基本思路都是把子串表示为后缀的前缀,用总数减去后缀之间的 \(\operatorname{LCP}\),也即 \(ht_i\)。
P2408 不同子串个数
答案是 \(\sum \limits_{i=1}^n i - ht_i\)。
AT_s8pc_2_e 部分文字列
计算本质不同子串的长度和,只需要把计算前缀数量改成计算前缀长度和。
CF653F Paper task
思路是计算所有合法括号子串数量,再减去算重复的。
3.最长公共子串
基本思路是在 \(rk\) 数组上双指针维护,区间合法条件是区间内有所有串的后缀。用单调队列维护区间 \(ht\) 的最小值。
P5546 公共串
板子。
P2463 [SDOI2008] Sandy 的卡片
差分后就是在求最长公共子串。
SP1811 LCS - Longest Common Substring
板子。
SP1812 LCS2 - Longest Common Substring II
还是板子。
SP10570 LONGCS - Longest Common Substring
仍然是板子。
Match & Catch
最短公共子串,但是思路好像差不太多。
P5576 [CmdOI2019] 口头禅
并查集合并 \(ht\),每一组询问 \([l,r]\) 的答案就是第一次颜色段区间包含它的时候的 \(ht\) 值。set 维护连续段配合扫描线求解。
P9664 [ICPC2021 Macao R] LCS Spanning Tree
利用 SA 求 LCS 的过程删除无用的边。
4.并查集维护 \(ht\)
本质上维护的是 \(\text{Beginpos}\) 集合。实际上如果你把并查集合并的过程显示建出 Kruskal 重构树,再缩掉相同值的点就能得到后缀树。
P2178 [NOI2015] 品酒大会
最经典的题目了。
P6793 [SNOI2020] 字符串
贪心的匹配 \(\operatorname{LCP}\) 大的串。
CF802I Fake News (hard)
并查集维护子串的出现次数。
CF123D String
同上。
CF873F Forbidden Indices
串反过来即变成给定位置不能开头,并查集维护出现次数即可。
CF452E Three strings
并查集维护 \(\operatorname{LCP} \ge L\) 的串里 \(a,b,c\) 后缀的数量。
P7361 「JZOI-1」拜神
并查集维护 \(\operatorname{LCP}\),用数据结构辅助判断区间最长重复子串。
SP4311 Quasi-template
维护 \(\text{Beginpos}\) 集合后可以转化为二维数点。
5.设置关键点
这个 trick 主要求解重复串问题,形如 \(\text{AA}\) 的串如果我们隔 \(|\text A|\) 个位置放一个关键点,串一定恰好跨过两个关键点,枚举关键点可以做到调和级数复杂度。通常需要同时求出前缀的最长公共后缀和后缀的最长公共后缀。
P1117 [NOI2016] 优秀的拆分
求解 \(\text{AA}\) 串,把贡献记在开头结尾,并用乘法原理统计答案。
SP687 REPEATS - Repeats
枚举循环节长度,设置关键点统计答案。很妙的题。
WGOI R1 真夏飞焰
找到 \(\text{AA}\) 串,用并查集合并限制,倍增优化建图。好题!
UVA10829 L-Gap Substrings
以 \(i+k\) 为间隔设置关键点。
P5161 WD与数列
容斥后变为数相邻或相交的相等子串对数。
6.回文串相关
这一部分的套路是把反串拼在后面,回文半径即是正串和反串对应位置的 \(\operatorname{LCP}\)。
UVA11475 Extend to Palindrome
裸的求回文半径。
P9482 [NOI2023] 字符串
反串拼在后面,用 SA 比较后缀大小关系和求解回文半径,二维数点。
CF1913F Palindromic Problem
讨论修改破坏的回文串数量和增加的回文串数量,拼反串后求 \(\operatorname{LCP}\) 即可。
CF30E Tricky and Clever Password
贪心的让回文串长度最大。
7.字符串匹配相关
这一部分的经典套路是 \(rk\) 数组上二分 \(\operatorname{LCP} \ge len\) 的极长区间。题目变化多样。
CF547E Mike and Friends
二分出区间,问题相当于求位置在一个区间,\(rk\) 在一个区间的后缀数量,二维数点。
P2336 [SCOI2012] 喵星球上的点名
两次二维数点求解两个问题。
SP8093 JZPGYZ - Sevenk Love Oimaster
严格弱于上一题。
CF666E Forensic Examination
二分出 \(rk\) 区间以后转化为限定值域的区间众数问题,值域分块 + 莫队。
P4094 [HEOI2016/TJOI2016] 字符串
二分答案,相当于在线二维数点,可持久化线段树维护。
CF149E Martian Strings
枚举端点,贪心的让第一部分靠左,第二部分靠右,st 表维护。
AT_tenka1_2016_final_c たんごたくさん
枚举 \(|p_j|\),二分出排名区间,st 表找最大的 \(w\),然后 DP。轻微卡常。
CF232D Fence
差分,二分,二维数点。
CF1608G Alphabetic Tree
CF547E 上树,用哈希找到第一个字典序大于等于询问串的第一个后缀。代码实现难度较大。
8.组合数学相关
CF1526E Oolimry and Suffix Array
用 \(rk\) 数组刻画字符的大小关系,然后插板法求解。
\(^*\) CF1266G Permutation Concatenation
很厉害的题,但是我不会 qwq。
9.更多题目
比较杂或者比较综合的题,我也不知道该放哪里了 qwq。
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 全网最简单!3分钟用满血DeepSeek R1开发一款AI智能客服,零代码轻松接入微信、公众号、小程
· .NET 10 首个预览版发布,跨平台开发与性能全面提升
· 《HelloGitHub》第 107 期
· 全程使用 AI 从 0 到 1 写了个小工具
· 从文本到图像:SSE 如何助力 AI 内容实时呈现?(Typescript篇)