CF1120C Compress String 题解

简要题意:你需要打出一个长度为 n 的字符串 s

  • 花费 c1 的代价,在末尾打出一个字符。
  • 花费 c2 的代价,在末尾打出目前已打出字符串的某个子串。

问最少的操作代价,n5×103

不妨用 fi 表示操作前 i 个数的最小代价。可以在枚举当前点 i 时再枚举一个之前点 j。如果  1lrj,a[j+1i]=a[lr] 就进行一次转移。暴力去判断子串相等就是 O(n3) 的复杂度。
可以配合 hash,还要线段树维护 set。第 iset si 储存 {x|x=a[pi],1pi}hash 值,查询相当于在一段前缀 set 中查询一个元素是否存在。不过这样又要用线段树又需要 set,复杂度 O(n2log2n),就算使用 unordered_set 还得承受大常数 O(n2logn)
发现不管怎么做,询问的东西都是一样的,先预处理出所有询问,按照每个询问的 i 排序。这样每次询问都在一段前缀中进行。排序询问的复杂度是 O(n2logn),后续查询采用 unordered_set,复杂度 O(n2)。总复杂度为 O(n2logn)
也可以维护原串的最长公共后缀,由于 f 具有单调性(假如 fi>fi+1 必然是操作 2 使得这种情况发生,那我操作 2 少粘贴一个字母就能使得 fi=fi+1,也就是说假设必然不成立,f 具有单调性,fifi+1),每次应该从最小的 j 转移过来,这个最小的 j 就是之前某个 ji 的最大公共后缀。复杂度 O(n2)
在这个做法的基础上,在后缀自动机上跑双指针(ij),a[ji] 存在就转移,否则 j 右移。复杂度 O(n)

posted @   蒟酱  阅读(19)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
· 【杂谈】分布式事务——高大上的无用知识?
点击右上角即可分享
微信分享提示