把lcm离散化一下就能过了。
#include<bits/stdc++.h> #define LL long long #define fi first #define se second #define mk make_pair #define PLL pair<LL, LL> #define PLI pair<LL, int> #define PII pair<int, int> #define SZ(x) ((int)x.size()) #define ull unsigned long long using namespace std; const int N = 1e6 + 7; const int inf = 0x3f3f3f3f; const LL INF = 0x3f3f3f3f3f3f3f3f; const int mod = 1e9 + 7; const double eps = 1e-8; int T, s[20], tot, hs[N], hcnt, who[N]; int Lcm[2521][2521]; LL L, R, f[20][2521][50]; inline int getId(int x) { return lower_bound(hs + 1, hs + 1 + hcnt, x) - hs; } LL dp(int len, int mo, int lcm, bool limit) { if(len == -1) return mo % hs[lcm] ? 0 : 1; if(!limit && ~f[len][mo][lcm]) return f[len][mo][lcm]; LL ans = 0; int up = limit ? s[len] : 9; for(int i = 0; i <= up; i++) { ans += dp(len - 1, (mo*10+i)%2520, i ? who[Lcm[i][hs[lcm]]] : lcm, limit && up == i); } if(!limit) f[len][mo][lcm] = ans; return ans; } LL solve(LL x) { tot = 0; for(LL i = x; i; i /= 10) s[tot++] = i % 10; return dp(tot - 1, 0, 1, 1); } int main() { for(int i = 0; i < (1 << 9); i++) { int tmp = 1; for(int j = 0; j < 9; j++) if(i >> j & 1) tmp = tmp / __gcd(tmp, j + 1) * (j + 1); hs[++hcnt] = tmp; } sort(hs + 1, hs + 1 + hcnt); hcnt = unique(hs + 1, hs + 1 + hcnt) - hs - 1; for(int i = 1; i <= 2520; i++) who[i] = getId(i); memset(f, -1, sizeof(f)); for(int i = 1; i <= 2520; i++) for(int j = 1; j <= 2520; j++) Lcm[i][j] = i / __gcd(i, j) * j; scanf("%d", &T); while(T--) { scanf("%lld%lld", &L, &R); printf("%lld\n", (solve(R) - solve(L - 1))); } return 0; } /* */