最小回文分解学习笔记

具体可以看这篇论文:https://arxiv.org/pdf/1403.2431v2.pdf
这篇文章其实是半搬该论文半搬别人博客的
最小回文分解:Minimum Palindromic Factorization
我们令 P L ( S ) PL(S) PL(S)表示S的最小回文分解。
那么令len为S的长度。

我们有一个不等式:
P L ( S [ 1.. i ] ) − 1 ⩽ P L ( S [ 1... i + 1 ] ) ⩽ P L ( S [ 1.. i ] ) + 1 PL(S[1..i])-1\leqslant PL(S[1...i+1])\leqslant PL(S[1..i])+1 PL(S[1..i])1PL(S[1...i+1])PL(S[1..i])+1
证明:
后半部分显然,考虑如何证明前半部分。
如果S[1…i+1]的回文划分是 S 1 , S 2 . . . S l − 1 , S [ h . . . i + 1 ] S_{1},S_{2}...S_{l-1},S[h...i+1] S1,S2...Sl1,S[h...i+1]
那么我们很明显可以将S[1…i+1]划分成 S 1 , . . . , S l − 1 , S [ h ] , S [ h + 1... i ] S_{1},...,S_{l-1},S[h],S[h+1...i] S1,...,Sl1,S[h],S[h+1...i]

接下来,我们会给出一个时间复杂度为 O ( n l o g n ) O(nlogn) O(nlogn),空间为 O ( n ) O(n) O(n)的算法。

引理1:
如果y是回文串x的前缀并且y是回文串,那么y是x的border。

引理2:
如果y是x的border并且 ∣ x ∣ ⩽ ∣ 2 y ∣ |x|\leqslant |2y| x2y,那么x是回文串当且仅当y是回文串。

引理3:
如果y是回文串x的前缀,那么 ∣ x ∣ − ∣ y ∣ |x|-|y| xy是x的循环节当且仅当y是个回文串。
并且 ∣ x ∣ − ∣ y ∣ |x|-|y| xy是x的最小循环节当且仅当y是x的最长回文前缀。

引理4:
x是个回文串。y是x的最长回文前缀。z是y的最长回文前缀。
那么x可以表示成uy,y可以表示成vz。
(1) ∣ u ∣ ⩾ ∣ v ∣ |u|\geqslant |v| uv
证明:如果不成立,那么u可以成为y的最小循环节,与v为y的最小循环节矛盾。
(2) i f   ∣ u ∣ > ∣ v ∣ , 那 么 ∣ u ∣ > ∣ z ∣ if\ |u|>{}|v|,那么|u|>|z| if u>vu>z
证明:可以注意到,如果题干成立,那么v是u的一个前缀,也是x的一个前缀。
我们可以将x表示成vw
因为 ∣ u ∣ > ∣ v ∣ |u|>|v| u>v,那么 ∣ w ∣ > ∣ y ∣ |w|>|y| w>y
采用反证法,如果 ∣ u ∣ ⩽ ∣ z ∣ |u|\leqslant |z| uz
那么 ∣ w ∣ = ∣ z u ∣ ⩽ 2 ∣ z ∣ |w|=|zu|\leqslant 2|z| w=zu2z
注意到z是w的border。(后缀显然,前缀因为y=vz为vw的前缀)
那么根据引理2,w是回文串。那么w是x的前缀。
这样,y是x的最长回文前缀不成立。
(3) i f   ∣ u ∣ = ∣ v ∣ , t h e n   u = v if\ |u|=|v|,then\ u=v if u=v,then u=v
显然。
根据引理4,我们可以发现一个回文串border之间的差递减,且可以划分成 O ( l o g n ) O(log_{n}) O(logn)个差相等的部分。

以下参考自博客:https://www.cnblogs.com/King-George/p/9612816.html
到这里,我们考虑如何求出最小回文分解。
我们建出回文树。
a n c u = { a n c f a i l u , ( l e n u − l e n f a i l u = = l e n u − l e n f a i l f a i l u ) u ( o t h e r w i s e ) anc_{u}=\begin{cases} & \text anc_{fail_u},(len_{u}-len_{fail_u}==len_u-len_{fail_{fail_u}})\\ & \text u(otherwise) \end{cases} ancu={ancfailu,(lenulenfailu==lenulenfailfailu)u(otherwise)
如果我们不停执行 u = f a i l a n c u u=fail_{anc_u} u=failancu,那么我们至多执行 O ( l o g n ) O(log_n) O(logn)
有点树连剖分的感觉。
那么我们令 S u = { v ∣ a n c v = a n c u , v = f a i l ( f a i l ( . . . f a i l ( u ) ) ) } S_{u}=\left \{v|anc_{v}=anc_{u},v=fail(fail(...fail(u)))\right \} Su={vancv=ancu,v=fail(fail(...fail(u)))}
在dp转移时每次会有, f i = m i n v ϵ S u { f i , f i − l e n v + 1 } f_{i}=min_{v\epsilon S_u}\left \{f_{i},f_{i-len_v}+1\right \} fi=minvϵSu{fi,filenv+1}
其中 S u S_u Su最多 l o g i log_i logi个。
注意到,所有在 i − ( l e n u − l e n f a i l f a i l u ) , f a i l u i-(len_u-len_{fail_{fail_u}}),fail_u i(lenulenfailfailu),failu处转移到的v会在i,u处转移到。且i,u多转移到的便是 f i − l e n a n c u f_{i-len_{anc_u}} filenancu
当然,前提是 a n c u ≠ u anc_u\neq u ancu̸=u.
那,我们记录rem_u为当前经历到u的最后的i转移到的v的最小值。那么当前i经历到的u的 r e m u rem_u remu需要根据 r e m f a i l u a n d f i − l e n a n c u rem_{fail_u}and f_{i-len_{anc_u}} remfailuandfilenancu来更新(当然,前提也是 a n c u ≠ u anc_u\neq u ancu̸=u)。
当然这里,我们需要证明对于 i ϵ ( i − ( l e n u − l e n f a i l u ) , i ) i\epsilon(i-(len_u-len_{fail_u}),i) iϵ(i(lenulenfailu),i),i不会经过 f a i l u fail_u failu
证明略。主要抓住: l e n u − l e n f a i l u = l e n f a i l u − l e n f a i l f a i l u len_u-len_{fail_u}=len_{fail_u}-len_{fail_{fail_u}} lenulenfailu=lenfailulenfailfailu
具体代码可以看CF906E。不过它那里的要求和最小回文分解的要求有些出入。

完结撒花!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值