Cf d. Beautiful numbers (Digital dp), numbersdp
Http://codeforces.com/problemset/problem/55/D
Beautiful Numbers: This number can divide all its bits from non-zero integers. Ask the number of Beautiful Numbers between [l, r.
If a number can divide all its non-zero digits, it is equivalent to the minimum public multiple of the individual digits. Therefore, apart from the len (current BIT) and up (whether the upper limit is reached) parameters in the memory search, there is a prelcm that represents the minimum public multiple of the previous number and determines whether the number isBeautiful Numbers also has a parameter that represents the previous number, but this number is too large and needs to be reduced.
Difficulties:
Narrow the range of the preceding number.
We can find that the minimum public multiple of all single digits is 2520. Assume that the currentBeautiful Numbers is x,
Then x % lcm {dig [I]} = 0,
And 2520% lcm {dig [I]} = 0,
Then x % 2520% lcm {dig [I]} = 0, x range from 9*10 ^ 18Change to 2520.
Handle out-of-memory issues.
After analysis, you can set dp [20] [2050] [2050]. dp [I] [j] [k] indicates that the data is processed to the I bit, the minimum public multiple of the preceding number is j, and the Number % 2520 is k. However
It's obvious that it's TLE .. Because 1 ~ The minimum public multiple of 9 is 48, which can be discretization, so that the array is reduced to dp [20] [50] [2520].
# Include <stdio. h> # include <iostream> # include <map> # include <set> # include <list> # include <stack> # include <vector> # include <math. h> # include <string. h> # include <queue> # include <string> # include <stdlib. h> # include <algorithm> // # define LL _ int64 # define LL long # define eps 1e-12 # define PI acos (-1.0) using namespace std; const int INF = 0x3f3f3f; const int maxn = 4010; const int max_lcm = 2520; LL gcd (L L a, LL B) {if (B = 0) return a; return gcd (B, a % B);} LL lcm (LL a, LL B) {return a/gcd (a, B) * B;} int dig [25]; LL dp [25] [50] [2525]; int hash [2525]; LL dfs (int len, int prelcm, int prenum, int up) {if (len = 0) {return prenum % prelcm = 0;} if (! Up & dp [len] [hash [prelcm] [prenum]! =-1) return dp [len] [hash [prelcm] [prenum]; int n = up? Dig [len]: 9; LL res = 0; for (int I = 0; I <= n; I ++) {int nownum = (prenum * 10 + I) % max_lcm; int nowlcm = prelcm; if (I) nowlcm = lcm (prelcm, I); res + = dfs (len-1, nowlcm, nownum, up & I = n) ;}if (! Up) dp [len] [hash [prelcm] [prenum] = res; return res;} LL cal (LL num) {int len = 0; while (num) {dig [++ len] = num % 10; num/= 10;} return dfs (len, 1, 0, 1) ;}int main () {int test; LL, b; int cnt = 0; for (int I = 1; I <= 2520; I ++) // discretization {if (max_lcm % I = 0) hash [I] = ++ cnt;} scanf ("% d", & test); memset (dp,-1, sizeof (dp )); for (int item = 1; item <= test; item ++) {scanf ("% I64d % I64d", & a, & B ); printf ("% I64d \ n", cal (B)-cal (A-1);} return 0 ;}