【浅谈数位计数一类问题】

背景: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)。

 

 

posted @ 2014-04-13 22:58  Chellyutaha  阅读(279)  评论(0编辑  收藏  举报