## ramay7

https://ramay7.github.io/

# Codeforces 55D Beautiful Numbers(数位dp，能被自己各个位上数字整除的数字个数)

Codeforces 55D Beautiful Numbers

dp[pos][rem][id[lcm]]pos2520remlcmid[lcm]

#include <stdio.h>
#include <math.h>
#include <string.h>
#include <algorithm>
using namespace std;
typedef long long ll;
const int mod = 2520;

ll L, R;
int id[2550], total, digit[20], T;
ll dp[20][2550][50];

void init()
{
total = 0;
for (int i = 1; i <= mod; ++i) {
if (mod % i == 0) {
id[i] = total++;
}
} // total = 48
}

ll dfs(int pos, int rem, int lcm, int limit)
{
if (pos == -1) return rem % lcm == 0;
if (!limit && dp[pos][rem][id[lcm]] != -1) return dp[pos][rem][id[lcm]];
int last = limit ? digit[pos] : 9;
ll ret = 0;
for (int i = 0; i <= last; ++i) {
int nxt = lcm;
if (i) nxt = i / __gcd(lcm, i) * lcm;
ret += dfs(pos - 1, (rem * 10 + i) % mod, nxt, limit && (i == last));
}
if (!limit) dp[pos][rem][id[lcm]] = ret;
return ret;
}

ll solve(ll n)
{
memset(dp, -1, sizeof(dp));
memset(digit, 0, sizeof (digit));
int len = 0;
while (n) {
digit[len++] = n % 10;
n /= 10;
}
return dfs(len - 1, 0, 1, 1);
}

int main()
{
init();
scanf("%d", &T);
while (T--) {
scanf("%I64d%I64d", &L, &R);
printf("%lld\n", solve(R) - solve(L - 1));
}
return 0;
}

10-12 158

03-19 429

08-26 1020

01-24 190

08-13 295

02-13 3225

05-01 215

09-08 366

09-19 132

09-01 612