题意:统计某段区间内满足它所有非零数位能整除这个数本身的数的个数。
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.PrintWriter;
import java.math.BigInteger;
import java.util.Arrays;
import java.util.Scanner;
import java.util.Set;
import java.util.TreeSet;
public class Main {
public static void main(String[] args) {
new CF_55D().run();
}
}
class CF_55D {
void run() {
Scanner cin = new Scanner(new BufferedInputStream(System.in));
PrintWriter cout = new PrintWriter(new BufferedOutputStream(System.out));
int t = cin.nextInt();
while (t-- > 0) {
long l = cin.nextLong(), r = cin.nextLong();
cout.println(calculation(r) - calculation(l - 1));
}
cout.flush();
}
long calculation(long val) {
int bit = 0;
while (val > 0) {
dight[bit++] = (int) (val % 10);
val /= 10;
}
return dfs(bit - 1, 0, 1, true);
}
long dfs(int pos, int sum, int lcm, Boolean isEnd) {
if (pos < 0)
return sum % lcm == 0 ? 1L : 0L;
if (!isEnd && dp[pos][sum][hash[lcm]] != -1)
return dp[pos][sum][hash[lcm]];
int end = isEnd ? dight[pos] : 9;
long res = 0L;
for (int i = 0; i <= end; i++) {
res += dfs(pos - 1, (sum * 10 + i) % N, lcm(lcm, i), isEnd && i == end);
}
if (!isEnd)
dp[pos][sum][hash[lcm]] = res;
return res;
}
final int N = 2520;
long[][][] dp = new long[19][N][48];
int[] dight = new int[19];
int[] hash = new int[N + 8];
{
int cnt = 0;
for (int i = 1; i <= N; i++) {
if (N % i == 0)
hash[i] = cnt++;
}
for (int i = 0; i < 18; i++) {
for (int j = 0; j < N; j++)
Arrays.fill(dp[i][j], -1);
}
}
int gcd(int x, int y) {
return y == 0 ? x : gcd(y, x % y);
}
int lcm(int x, int y) {
if (x == 0)
return y;
if (y == 0)
return x;
return x / gcd(x, y) * y;
}
}