topic link : [Kuangbin take you to fly] topic XV digital DP a-beautiful numbers
Test instructions
PS: The first digital DP, the problem is really good, although it is a reference to the Daniel method has been a, but still a lot of harvest.
Find out how many beautiful numbers are in a range. Beautiful numbers means: A number can divide all the non-0 numbers that make up it.
For example 15 can be divisible by 1 and 5, so 15 is beautiful numbers.
Ideas
Beautiful numbers means: A number can divide all the non-0 numbers that make up it.
Equivalent to a number that divides the least common multiple of all the non-0 numbers that make up it.
We see the scope of the data is 1?≤?li?≤?ri?≤?9? 1018, cannot be recorded at all.
So narrowing the scope becomes the first thing to do.
Look at a small formula first.
sum%(x*n)%x == sum%x;证明:设sum = k*x+b 等号左边: sum%(x*n)%x -> (k*x+b)%(x*n)%x 将k转为ka*n + kb代入; (ka*n*x+kb*x+b)%(x*n)%x -> (kb*x+b)%x -> b%x -> b 等号右边: b左右相等,证明成立
Then we can use the X*n in the formula to take the remainder of NUM, record its value after the remainder, obviously, 1~9 least common multiple 2520 is the most reasonable x*n.
And in the bit-wise statistics, can be directly from the previous bit after the value of the remainder to obtain a new digit after the remainder of the value.
For example, RX (R is the value after the previous bit is known), then rx%2520 = = (r*10+x)%2520. I'm not going to pass this crap.
We use memory search.
**DFS (len, num, LCM, flag)
Len represents the length of the iteration,
Num is the value of the number to 2520 of the current bit, after the remainder is taken.
The LCM is the least common multiple of all the numbers for the current bit.
Flag indicates whether the current number can be arbitrarily evaluated (judging the upper limit) * *
DP[LEN][NUM][LCM] can be used to record it.
However, LCM by 2520 value is not open, so the LCM is discretized, because the LCM must be divisible by 2520, so the 1~2520 can be divisible by 2520 of the number to mark it, after testing found only 48, to meet the current situation.
Code
#include <iostream>#include <algorithm>#include <cstring>#include <cstdio>#include <cstdlib>#include <vector>using namespace STD;#define LL Long LongConst intMOD =2520; LL dp[ -][ -][2550];intdis[ -];inthash[2550]; ll GCD (ll A, ll b) {returnB?GCD (b,a%b): A;} LL DFS (intLenintNumintLcmBOOLFlag) {if(-1==len)returnNUM%LCM = =0;if(!flag &&-1==dp[len][hash[lcm]][num])returnDp[len][hash[lcm]][num]; LL ans =0;intEnd = Flag?dis[len]:9; for(intI=0; i<=end; i++) ans + = DFS (len-1, (num*Ten+i)%mod, I?LCM*I/GCD (lcm,i): LCM, Flag&&i==end);if(!flag) Dp[len][hash[lcm]][num] = ans;returnAns;} ll solve (ll N) {intpos =0; while(n) {dis[pos++] = n%Ten; N/=Ten; }returnDFS (pos-1,0,1,1);}intMain () {intTscanf("%d", &t);intCNT =0; for(intI=1; i<=mod; i++)if(mod%i = =0) Hash[i] = cnt++;memset(DP,-1,sizeof(DP)); while(t--) {Long LongL, R;scanf("%lld%lld", &l, &r);printf("%lld\n", Solve (R)-solve (l1)); }return 0;}
Codeforces 55D Beautiful Numbers (digital dp&& discretization)