Beautiful numbers
time limit per test:4 seconds
memory limit per test:256 megabytes
input:standard input
output:standard output
Volodya is an odd boy and his taste is strange as well. It seems to him that a positive integer number is beautiful
Input
The first line of the input contains the number of cases t (1 ≤ t ≤ 10). Each of the next t lines contains two natural numbers li and ri (1 ≤ li ≤ ri ≤ 9 ·1018).
Please, do not use %lld specificator to read or write 64-bit integers in C++. It is preffered to use cin (also you may use %I64d).
Output
Output should contain t numbers — answers to the queries, one number per line — quantities of beautiful numbers in given intervals (from li to ri, inclusively).
Examples
Input
1 1 9
Output
9
Input
1 12 15
Output
2
很明显的一道数位dp,但是转移却并不是那么好想。
大致题意是,让你求区间内所有的能够每一位数字整除的数字有多少个。
最初始的想法是,设置dp[len][x]表示长度为x时且当前为x的倍数的时候的数量,但是在考虑转移的时候却发现,不能很好的处理这个倍数整除关系,每次新加入一个数字就会产生一个新的因子。于是抛弃这个想法。这里,我们考虑利用一些同余的性质,若a≡b(mod m) 且d|m 则a≡b(mod d)。我们可以知道,lcm(1~9)=2520,若a≡b(mod 2520) 且xi|2520 则a≡b(mod xi) 。is strange 那么,所有满足%xi==0的数字一定满足%2520==0,有了一个必要条件。根据这个,我们就能够把每个数字的%2520之后的具体大小当作dp数组的参数,也即可以知道每个数字对xi取模后的数值。根据这个,再在转移的时候加上当前已经选取过的数字的lcm,就可以完成转移。
具体来说,设dp[len][mod][lcm]表示当前长度为len,数字对2520取模之后的大小为mod,已取数字LCM为lcm时的方案数。有转移方程dp[len][mod][lcm]=Σdp[len-1][(mod*10+xi)%2520][__lcm(xi,lcm)]。按照正常数位dp的方式转移求即可。另外还要注意空间,正常来说,最后一维lcm最大也可以取到2520,但是这样19*2520*2520,即使是256M的内存也会超。但是真正的lcm并没有那么多,我们可以预先dfs出所有可能出现的lcm的数值,然后重标号即可,事实正名最多只有48个lcm的数值,一一对应即可。具体见代码: