【题解】CF700E Cool Slogans

原题面很简洁,懒得概括了。

思路

后缀自动机 + 结论。

这种题出题人没有十年脑血栓都没法出。

结论 1:si1 必定是 si 的后缀。

考虑 sisi1 最后一次出现位置,记为 p。对于 sip 之后的位置,把它们截去不影响 si1si 中的出现次数,并且 sisi+1 中的出现次数可能增加,因此截去一定不劣,故而可以令 si1 必定为 si 的后缀。

结合 parent tree 的性质:祖先结点必定是后代结点的后缀,可以联想到在 parent tree 上跑一次从上到下的 dp 求最长链,dp 转移的条件是祖先结点代表的串在后代的串中至少出现 2 次。

如何判定转移的条件?

考虑到祖先串一定是后代串的后缀,即至少在后代串中出现 1 次。令 u,v 分别为祖先串和后代串,pendpos(v) 中任意元素,则当 endpos(u) 中包含 [plen(v)+len(u),p1] 中任意元素时,uv 中至少出现 2 次。

于是可以考虑用线段树合并维护每个结点的 endpos,判定可以 O(log) 用线段树查询。

然而现在的问题是:parent tree 上的结点代表整个等价类,转移的时候应该用哪一个串?

结论 2:转移时等价类中所有串都是等价的。

考虑反证。假设 s 是某一结点 u 表示的等价类中最长的串,v 是结点 u 的祖先,串 1 和串 2 都是结点 v 的等价类中的串。

不妨假定串 1 是 abcb,串 2 是 babcb,串 sabcbabcb,则串 1,s 之间可以转移而串 2,s 之间不可以转移。

如果存在另一个可以和串 2 转移的串 3,不妨假定为 babcbabcb,那么因为 su 等价类中最长的串,所以串 3 一定来自另一个以 v 为祖先的等价类中。

在上面的反例中,串 3 所在的等价类以 u 为祖先,记这个等价类为 w。根据 parent tree 的定义有:

|endpos(u)|>|endpos(w)|

也就是存在位置 p|endpos(u)||endpos(w)| 使得该位置存在串 s 而不存在串 3.

那么该位置出现了 2 次串 1 而只出现了 1 次串 2,与串 1 和串 2 在同一等价类中矛盾,得证。

所以转移的时候只需要取最长串即可。

那么在 parent tree 上进行一次从上往下的 dp 求最长链,转移的时候用线段树判定即可。

代码

有亿 丶难调。

posted @   kymru  阅读(22)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现
点击右上角即可分享
微信分享提示
主题色彩