凡是大于3维的状态我都莫名的想用记忆化省去一维 写法一样
注意要离散化LCM值 不然数组开不下 而且CF还报一个奇怪的错 看了我好久
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<iostream>
using namespace std;
typedef long long LL;
const int MAXL = 2520;
const int MAXN = 30;
LL d[MAXN+10][MAXL+10][60];
int bit[MAXN+10], Num[MAXL+10], Goback[MAXL+10], cnt;
int gcd(int x, int y)
{
while(y)
{
int r = x % y;
x = y;
y = r;
}
return x;
}
LL dp(int h, int sum, int lcm, bool limit)
{
if(h == 0) return (sum % Num[lcm]) ? 0 : 1;
if(d[h][sum][lcm] != -1 && !limit) return d[h][sum][lcm];
lcm = Num[lcm];
LL ans = 0;
int ed = limit ? bit[h] : 9;
for(int i = 0; i <= ed; i++)
{
int Newlcm;
if(i == 0) Newlcm = lcm;
else Newlcm = lcm / gcd(lcm, i) * i;
ans += dp(h-1, (sum * 10 + i) % MAXL, Goback[Newlcm], limit && i == ed);
}
if(!limit) d[h][sum][Goback[lcm]] = ans;
return ans;
}
LL solve(LL X)
{
int Len = 0;
memset(bit, 0, sizeof(bit));
while(X) {
bit[++Len] = X % 10;
X /= 10;
}
return dp(Len, 0, 1, 1);
}
void init()
{
cnt = 0;
memset(d, -1, sizeof(d));
for(int i = 1; i <= MAXL; i++)
if(!(MAXL % i))
Num[++cnt] = i, Goback[i] = cnt;
}
int main()
{
init();
int T; scanf("%d", &T); while(T--)
{
LL L, R;
cin >> L >> R;
LL ans = solve(R) - solve(L-1);
cout << ans << '\n';
}
}