字符串科技:Palindrome Series

简介

其实不太清楚这个应该叫什么,知道的同学可以麻烦告知我。
众所周知,一个串的border数量是 O ( n ) O(n) O(n)的,但是他们可以用 O ( l o g n ) O(logn) O(logn)段等差数列表示。
这个东西叫做Border Series,然后把他和回文串结合起来放在PAM上使用,就是本文说的Palindrome Series了。
这东西代码实际非常短,使用的时候,只需要修改3行(DP转移部分)。

背景知识

弱周期定理

这里不详细展开讲,这是一个well known的定理,在使用Series相关的科技时会反复用到,可以自行搜索了解。

Border Series

一个串的长度在 [ 2 k , 2 k + 1 ) [2^k,2^{k+1}) [2k,2k+1)范围内的border长度构成等差数列,证明使用上面的弱周期定理,可以参考2019国集论文等很多资料,不讲。

Palindrome Series

考虑一个回文串 S S S的后缀 T T T,则有: T T T是回文串与 T T T S S S的border 等价。再结合上面的Border Series,即可得到一个推论:一个回文串的所有回文后缀可以表示为 O ( l o g n ) O(logn) O(logn)段等差数列。设法对每段等差数列进行维护,就可以 O ( l o g n ) O(logn) O(logn)枚举所有回文后缀,这就是Palindrome Series做的事情。

PAM

前置技能点:Palindrome Automaton,回文自动机。

例题:CF 932G

题意

转化之后的题意为:给一个串 S ( ∣ S ∣ ≤ 1 0 6 ) S(|S| \le 10^6) S(S106),规定一个 S S S的分割是合法的当且仅当:分割的每一部分都是偶回文串。

求合法的分割方案数。

题解

暴力DP

很容易直接想到暴力DP的办法:设 f [ i ] f[i] f[i]表示将串 S [ 1 , i ] S[1,i] S[1,i]进行分割的方案数。

初始化 f [ 0 ] = 0 f[0] = 0 f[0]=0,转移为

f [ i ] = ∑ 1 ≤ j < i f [ j ] ⋅ [ S [ j + 1 , i ] 是 偶 回 文 串 ] f[i] = \sum_{1 \le j < i} f[j] \cdot [S[j+1,i]是偶回文串] f[i]=1j<if[j][S[j+1,i]]

也就是我们需要枚举所有 S [ 1 , i ] S[1,i] S[1,i]的(偶)回文后缀。使用PAM,全 a a a串的复杂度为 O ( n 2 ) O(n^2) O(n2),不能通过。

使用Palindrome Series优化DP

符号约定

l e n [ i ] len[i] len[i] 表示节点代表的回文串长度
f a i l [ i ] fail[i] fail[i] 表示节点的失配指针,即最长的回文后缀,即最大border。
d i f f [ i ] = l e n [ i ] − l e n [ f a i l [ i ] ] diff[i] = len[i] - len[fail[i]] diff[i]=len[i]len[fail[i]] ,表示一个节点和他最大border长度的差,即所在的等差数列的公差。
a n c [ i ] anc[i] anc[i] 表示节点所在等差数列的首项位置,即从 i i i开始往根走,保证 d i f f diff diff值都相同,最终走到的点。
g [ i ] g[i] g[i] 维护每个点到链顶的信息,维护的范围是 ( l e n [ a n c [ i ] ] , l e n [ i ] ] (len[anc[i]],len[i]] (len[anc[i]],len[i]],公差 d = d i f f [ i ] d = diff[i] d=diff[i]
f [ i ] f[i] f[i] 表示 D P DP DP值,即将串 S [ 1 , i ] S[1,i] S[1,i]进行分割的方案数。

转移方法

l e n , f a i l , d i f f , a n c len,fail,diff,anc len,fail,diff,anc都可以在构造 P A M PAM PAM的过程中求得。
重点在于 f , g f,g f,g的相互转移。
根据定义: f [ i ] = ∑ p g [ p ] f[i] = \sum_{p} g[p] f[i]=pg[p],其中 p p p是在PAM上跳到的点,跳的方式是每次从 p p

  • 8
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值