Codeforces 932G Palindrome Partition dp+回文树

博客讲述了如何解决Codeforces上的一道题目932G,该题要求将一个偶数长度的字符串按照特定条件划分成若干部分,每部分形成回文串。博主分析了直接解法的不可行性,并提出通过构造回文串和利用回文树优化的方法,将问题转化为求解偶数长度回文串的划分方案数。讨论了回文串的性质,特别是回文串的border与等差数列的关系,并描述了如何维护回文树节点的等差数列信息以优化算法。
摘要由CSDN通过智能技术生成

题意

给出一个长度为偶数的字符串S,要求把S分成k部分,其中k为任意偶数,设为a[1..k],且满足对于任意的i,有a[i]=a[k-i+1]。问划分的方案数。
n<=1000000

分析

刚了一个下午的题,感觉学到了很多新东西。
首先直接做显然不可做,考虑把S变成S[1]S[n]S[2]S[n-1]…S[n/2]S[n/2+1]的形式,不难发现对于原来划分方案中的a[i]和a[k-i+1],它们在新串中恰好连续且组成一个回文串。那么问题就变成了把新串划分成若干部分,使得每一部分都是偶回文串,问方案。
一开始的想法是把回文树建出来,然后设f[i]表示把前i个字符划分的方案数,然后枚举i的每一个回文后缀进行转移。
这样子的复杂度是O(回文串数量)的,显然会超时,考虑如何优化。
有一个小结论就是一个回文串S的一个后缀T是回文串当且仅当T是S的border。
有一个性质就是一个串的所有border可以划分成O(log)段等差数列。
证明的话,可以考虑对于所有长度大于n/2的border,它们显然组成一个等差数列,然后把长度减半,如此类推,那么等差数列的数量就只有O(log)个。
对于回文树上的每个节点p,我们可以维护以它作为等差数列末项时每一项的f值之和g[p],维护nxt[p]表示节点p下一个等差数列的末项。
怎么维护呢?设当前节点为末项的等差数列有b1,b2,b3,其中b1>b2>b3。那么有g[p]=f[i-b1]+f[i-b2]+f[i-b3]。
根据回文串的性质,不难发现S[i-b2,i-d]=S[i

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值