Beautiful numbers CodeForces - 55D

Meaning of the questions:

Find the interval [li, ri] contain a number of minority meet, every bit of this number of non-zero number can be divided by this number

 

answer:

Because the values ​​of each bit can be divided by this number, it means that this number is a common multiple of all its digits, but may not be the least common multiple.

The least common multiple is 1,2,3,4,5,6,7,8,9 2520

Then I can make that we have to determine the number of fetch more than 2520 to achieve our memory operation

Because 2520 is the least common multiple 1--9, 1--9 so few numbers of any remainder of 2520 is certainly the least common multiple, so we just need to find out all the remainder in 1--25202520 on it. Finally, find out it 48

48 for this location of each mapping value

This way you can reduce the size and array dp

dp [x] [y] [z] represents: enumeration to x bit, modulo the number 2520 is the result y, the number of bits of the least common multiple of all current corresponding mapping z

 

Code:

1  // first requires you to be divisible by the number on, it can be a number divisible into question.
2  // This number is the least common multiple LCM (not GCD) everybody on the numbers.
3  // Second, deal with the problem divisible, was converted into a digital DP remainder template. LCM 1 ~ 9 maximum is 2520, then 2520%, so that it could open the memory array search.
4  // Finally, for the final result can not be% 2520% and then each digit accumulated over the LCM.
5  // This way, the need to open an array of 20 * 2520 * 2520, the CF to a post you will find the MLE.
6  // result (LCM = a * b / gcd (a, b)), that is to say all LCM is a carefully observed each of LCM, which ranges from 1 to 2520 Yes, it is divisible by gcd of number divisors.
7  // The number is actually 2520. So before DP, 2520 to make a table, the LCM to discrete Hash. This is actually only 48 of the LCM. Array open 20 * 2520 * 50 can be.
8  // Note that the result is int64. 
. 9 #include <stdio.h>
 10 #include < String .h>
 . 11 #include<algorithm>
12 #include<iostream>
13 #include<map>
14 using namespace std;
15 const int maxn=20;
16 const int mod=2520;
17 typedef long long ll;
18 ll v[maxn],dp[maxn][mod+50][50];
19 map<ll,ll>w;
20 ll lcm(ll a,ll b)
21 {
22     ll ans=min(a,b);
23     while(ans)
24     {
25         if(a%ans==0 && b%ans==0) break;
26         ans--;
27     }
28     return (a*b)/ans;
29 }
30 ll dfs(ll pos,ll sum,ll sta,bool limit)
31 {
32     if(sta==0)return 0;
33     if(pos==-1)
34     {
35         return sum%sta==0;
36     }
37     if(!limit && dp[pos][sum][w[sta]]!=-1) return dp[pos][sum][w[sta]];
38     ll up=limit?v[pos]:9;
39     ll tmp=0;
40     for(ll i=0;i<=up;++i)
41     {
42         if(i>0)
43         {
44             tmp+=dfs(pos-1,(sum*10+i)%mod,lcm(sta,i),limit && i==v[pos]);
45 
46         }
47         else tmp+=dfs(pos-1, (SUM * 10 + I)% MOD, STA, I limit && == V [POS]);
 48      }
 49      IF (limit) DP [POS] [SUM] [W [STA]] =! tmp;
 50      / / only the upper bound for the time will 9 to dp array stored inside, because it can save more time 
51 is      return tmp;
 52 is  }
 53 is  LL Solve (LL ANS)
 54 is  {
 55      LL POS = 0 ;
 56 is      the while (ANS)
 57 is      {
 58          V [POS ++] =% ANS 10 ;
 59          ANS / = 10 ;
 60      }
 61 is      return DFS (POS-1,0,1,true);
62 }
63 int main()
64 {
65     ll t,l,r,m=0;
66     scanf("%I64d",&t);
67     for(ll i=1;i<=mod;++i)
68     {
69         if(mod%i==0)
70         {
71             ++m;
72             w[i]=m;
73         }
74     }
75     memset(dp,-1,sizeof(dp));
76     while(t--)
77     {
78         scanf("%I64d%I64d",&l,&r);
79         printf("%I64d\n",solve(r)-solve(l-1));
80     }
81     w.clear();
82     return 0;
83 }

 

 

Guess you like

Origin www.cnblogs.com/kongbursi-2292702937/p/11926640.html