【CF 700E】Cool Slogans

CF 700E

Description

给出一个长度为 n 的字符串 str。你需要构造一个尽量字符串序列 s1,s2,,sk,满足:

  • 对于任意 1insistr 的子串。
  • 对于任意 1<insi1si 中至少出现了两次(可重叠)。

只需求出 k 的最大值即可。

数据范围:1n2×105
时空限制:4000 ms/500 MiB

Solution

引理 1

一定存在一种最优方案,使得 si1si 的 border。

证明

对于一个串 si,将其首尾多余的部分去掉,此时 si 即为 si1 的 border。按 i 从小到大将 si 的多余部分去掉即可得到满足该性质的方案。

根据「引理 1」,可以得知 si1si 的严格后缀。考虑将原串的 SAM 建出。

引理 2

在 SAM 的 parent 树上,对于任意一个状态 x 与其祖先状态 yy 表示的所有子串在 x 表示的最长串的出现次数相同。

证明

P2.png

反证法,考虑如图所示的子串结构。串 S 是状态 x 所表示的最长串;串 T1,T2 是状态 y 所表示的任意两个子串,这两个子串在 S 中的出现次数不同,必然会出现如图所示的结构。此时可以构造一个串 S 来使得 T1,T2S 中的出现次数相同。

由于 endpos(x)endpos(y),则出现 S 的地方,前面总会跟着一个串 T2。这样的话会使得 S,T2 组合成一个 S,可以推出 endpos(S)=endpos(S),这与 S 为状态 x 所表示的最长串矛盾,故假设不成立。

Q.E.D

根据「引理 2」,可以得知对于 SAM 的每个状态,我们都只需要记录其所表示的最长串的等级信息即可。

此时就可以在 parent 树上 dp,设 fi 表示从根到节点 i 的最大等级,设 gi 表示从根到节点 i 最大等级串的状态编号。

  • x 所表示的最长串中出现了两次 gFax 所表示的最长串,则

fx=fFax+1gx=x

  • 否则

fx=fFaxgx=gFax

运用可持久化线段树合并维护 endpos 集合,来判断每次是否可以成功转移。

时间复杂度 O(nlogn)

posted @   Calculatelove  阅读(33)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】
点击右上角即可分享
微信分享提示