[CF1110H]Modest Substrings[AC自动机、dp]

题意

给你一个范围 \([l,r]\) ,问长度为 \(n\) 的串最多有多少个子串满足大小在 \([l,r]\) 内。输出字典序最小的最优解。

\(1\le l \le r\le10^{800},1\le n\le 2000\)

分析

  • 如果 \(r-l​\) 较小可以将区间中所有的数字插入 AC 自动机然后 dp。

  • 考虑数位 dp 一类做法,如果当前的前缀没有抵到上下界后面的每一位都可以随便选,相当于 AC 自动机构建出来所有的儿子都是满的,尝试压缩这些节点。朴素的做法会在合法串的末尾统计这个串的贡献,现在则要在每个合法串 打破上下界的第一位 统计这个串的答案。

  • 考虑记录 g(i,j) 表示有多少 为 i 所代表的的串的后缀+在 i 这一位打破上下界后再走 j 步 的合法串。

    这样 AC 自动机中就只需要构建所有 未打破上下界的前缀+打破上下界的第一位 了。注意构建上界时,第一位为 0 的字符串非法。

    注意要把 fail(i) 的贡献继承,然后将 g 的意义变为前缀和。

  • 然后定义 f(i,j) 表示走了 i 步,走到 j ,最多有多少子串满足要求,每次累计对应的 g ,最后贪心找字典序最小的解即可。

  • AC自动机的总结点数 \(ndc\) 不超过 \(10\times (|L|+|R|)\) ,复杂度为 \(O(ndc \times n)\)

代码

代码链接

posted @ 2019-02-18 10:53  fwat  阅读(323)  评论(0编辑  收藏  举报