有时候一些神仙字符串题会用到 border 的性质来转化或者证明复杂度,记一下这些有用的结论。
记号:
-
字符串:s1,...,n,长度为 |s|
-
子串:s[l,r]
-
前 / 后缀:pre(s,i),suf(s,i) 分别表示字符串 s 长度为 i 的前 / 后缀。
-
最小周期:pre(s) 表示字符串 s 的最小周期。
令:
-
P(u,v)={k∣pre(u,k)=suf(v,k)}
-
LP(u,v)={k∈P(u,v),k≥|u|2
定义:
周期:∀0≤p<|s|,如果 ∀1≤i≤|s|−p 有 si=si+p,则称 p 是字符串 s 的一个周期。
border:若 ∀0≤r<|s|,有 pre(s,r)=suf(s,r),则称 pre(s,r) 是 s 的一个 border.
注意有时 border 的定义是 pre(s,r) 的长度。
border 和周期:
-
pre(s,k) 是 s 的 border ⇔ |s|−k 是 s 的周期。
-
若 p,q 都是 s 的周期,且 p+q≤|s|,则 gcd(p,q) 也是 s 的周期。
-
若 p,q 都是 s 的周期,且 p+q−gcd(p,q)≤|s|,则 gcd(p,q) 也是 s 的周期。
字符串匹配:
- 若字符串 u,v 满足 2|u|≥|v|,则 u 在 v 中匹配的位置是一个公差为 per(u) 的等差数列。此时 v 是 u 最小周期的重复。
border 的结构:
-
字符串 s 的所有不短于 |s|2 的 border 长度构成等差数列。
等价:本质不同的短于 |s|2 的 border 只有一个。
-
将 s 的 border 按长度划分成 [2i,2i+1−1),...,[2k,|s|) 等集合,则一个 border 集合可以表示成 LP(pre(s,2i),suf(s,2i))
-
LP(u,v) 构成一个等差数列。
-
推论:s 的所有 border 排序后可以划分成 O(log|s|) 段,每段是一个等差数列。
这个可以推出 P4482 [BJWC2018]Border 的四种求法 的 O(nlogn) 做法,非常强大。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 使用C#创建一个MCP客户端
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
2022-01-17 积性函数