[General idea ]:
The numbers 6 and 8 are both lucky numbers, and the multiples are also lucky numbers.
Evaluate the number of lucky numbers in the given range [l, r. (1 <= l, r <= 10,000,000,000)
[Analysis ]:
If you can find the number of lucky numbers in [1, n], the problem is solved.
First, calculate a number consisting of 6 and 8, and record it as the primLucky number. The number of lucky is several times the number of primLucky. Obviously, there is a principle of rejection.
Ai represents a set of numbers in [1, n] that are multiples of primluky [I.
By:
N | A1 1_a2... ∪ Am | = Σ n | Ai | 1 ≤ I ≤ m-Σ n | Ai sans Aj | 1 ≤ I ≤ j ≤ m + Σ n | Ai sans Aj sans Ak |-... + (-1) m-1) n | A1 1_a2... Running Am | 1 ≤ I, j, k ≤ m
Use dfs in the form of nesting.
The number of primLucky s generated between 1 and 10 digits can be:
Enumerate the length from 1 to 10 and determine the length of primLucky.
Or the I-long lucky is from the I-1-long lucky number + ending number is 6 or 8.
Code:
[Cpp]
# Include <stdio. h>
# Include <string. h>
# Include <algorithm>
# Include <ctype. h>
# Include <queue>
Using namespace std;
Typedef long ll;
Const int maxn = 1 <11;
Ll lucky [maxn];
Int len;
Const ll INF = commandid 000000000ll;
Inline ll gcd (ll a, ll B) {return B? Gcd (B, a % B): ;}
Ll lcm (ll a, ll B)
{
If (INF/a <B) {return INF ;}
Ll x = gcd (a, B );
Return a/x * B;
}
Inline bool get (ll & t)
{
Bool flag = 0;
Char c;
While (! Isdigit (c = getchar () & c! = '-') If (c =-1) break;
If (c =-1) return 0;
If (c = '-') flag = 1, t = 0;
Else t = c ^ 48;
While (isdigit (c = getchar () t = (t <1) + (t <3) + (c ^ 48 );
If (flag) t =-t;
Return 1;
}
Ll l, r;
Void init ()
{
Ll I, j, k, t, p, q, w;
For (I = k = 0; I <10; I ++)
{
// Enumerate the 68 I + 1 Length
W = I + 1;
For (j = 0; j <(1 <(I + 1); j ++)
{
P = 0; t = j; q = w;
While (q --)
{
P * = 10;
If (t & 1) p + = 8;
Else p + = 6;
T/= 2;
}
Lucky [k ++] = p;
}
}
Sort (lucky, lucky + k );
For (I = p = 1; I <k; I ++)
{
For (j = 0; j <p; j ++)
{
If (lucky [I] % lucky [j] = 0) break;
}
If (j = p) lucky [p ++] = lucky [I];
}
Len = p;
}
Ll dfs (int st, ll pre, ll n)
{
Ll ret = 0;
Int I;
For (I = 0; I <st; I ++)
{
Ll w = lcm (pre, lucky [I]);
If (w <= n) ret + = n/w-dfs (I, w, n );
}
Return ret;
}
Ll work (ll n)
{
If (n <6) return 0;
Return dfs (len, 1, n );
}
Void solve ()
{
Printf ("% lld \ n", work (r)-work (l ));
}
Int main ()
{
Init ();
While (get (l ))
{
Get (r );
L --;
Solve ();
}
}