背景:SDOI2014 DAY1 T2亮瞎了本渣的狗眼……自动机上跑数位Dp,于是本渣又看了看数位计数类问题(2009集训队2篇论文)
题目:一般都是涉及到要把整数拆分成各个位置上的书,讨论之间的一些关系;或者是涉及到进制问题(和拆分本质一样)
说明:
1、肯定是能暴力的……所以拿分不是问题
2、高效的方法一般都是分治,比如要询问一个很大的区间,就去分成各个小区间,而区间的选择一般都有特点性,根据题目的要求来划分区间,比较多的是按数的位数划分,如[0,9] [10,99] [100,999]……
3、划分上面的状态后一般都能写出递推的式子,所以能log级别合并区间
4、所以总体的时间效率很可观
————————————————————————————————————————————————
下面附上SDOI2014 DAY1 T2:
题意:计算不大于 N,且不包含 S 中任意一个数字串的数的个数
题解:
N = 10^l
的情况:计算长度为 l 1,不包含 S 中任意一个字符串
的字符串数量。
建出 S 的 AC 自动机;f(i;,j) 表示长度为 i,且最长的在自动机中
出现的后缀对应的节点为 j 的字符串数量。
用 f(i; j) 更新所有合法的 f(i + 1, next(j, c))。
O(lL)。
一般情况。
长度小于 l 的所有 (合法) 串都在统计范围内,用之前算法解决;
考虑长度等于 l 的串。
不考虑不包含 S 中串的限制,我们统计的数字串应当满足前 k
位与 N 相等,且第 k + 1 位小于 N 的对应位。
从高到低确定每一位;f(i,j,0) 表示前 i 位在自动机中对应节点
j,且前 i 位都与 N 相等的(i 位)串的数量;f(i, j,1) 表示前 i
位对应节点 j,且前 k < i 位与 N 相等,第 k + 1 位小于 N 的串
的数量。
f(i,j, 0) 更新 f(i + 1, next(j,Ni+1), 0)、
f(i+1, next(j,c), 1) (c < Ni+1,f(i, j, 1) 更新 f(i+1, next(j, c), 1)。
O(lL)。