問題の解決策
いくつかは、それはこれらの数字にする必要があり、数割り切れることができます\(LCM \)割り切れます
だから我々は、によると考える傾向がある\(LCM \)設定状態
我々はそれに便利かもしれません\(LCM \)のみ\(48 \) A
さて、平均ビット数に応じて\(DP \)
設定状態:\(F_ {I、J、K、0/1} \)前方を表す\(Iは\)ビット、\(LCM = Jが\) 、ダイ\(LCM \)残りのである(K \を\します)、上限か
(新たに追加されたモジュールの数は変化を生じ得るのため)が、この方法では転送できません
だから我々は、モジュールに統合している\(2520 \)
複雑\(O(T *のL * a * 2500 48 * 2)\)
前記\(Lの\)は入力ビットの数であります
そして、それはします\(TLE \)
それはほとんどの最適化を検討してください。
質問の複数のセットので。
あなたは多数を求めてきました場合は、
今回は、実際に私たちがすでに知っている答えの多くが求めています。
我々は、状態を取り除くことができます\(01 \)その次元。
このような複雑さは尋ねたグループの数を削除することができます。
特異的な第二のコードを参照してください。
コード
int gcd(int x, int y) {
return !y ? x : gcd(y, x % y);
}
int lcm(int x, int y) {
if (!x || !y) return x | y;
return x * y / gcd(x, y);
}
LL dfs(int x, int n, int m, int op) {
if (!x) return !num[n] || m % num[n] == 0;
if (f[x][n][m][op] != -1) return f[x][n][m][op];
LL &res = f[x][n][m][op]; res = 0;
for (int i = 0; i <= (op ? a[x] : 9); i++)
res += dfs(x - 1, M[lcm(num[n], i)], (m * 10 + i) % 2520, op & i == a[x]);
return res;
}
LL calc(LL x) {
if (!x) return 1;
l = 0;
while (x) a[++l] = x % 10, x /= 10;
for (int i = 1; i <= l; i++)
memset(f[i], -1, sizeof(f[i]));
return dfs(l, 0, 0, 1);
}
void solve() {
LL l = gi<LL>(), r = gi<LL>();
printf("%lld\n", calc(r) - calc(l - 1));
return ;
}
int main() {
for (int i = 1; i < (1 << 9); i++) {
int d = 0;
for (int j = 0; j < 9; j++)
if (i >> j & 1)
d = lcm(d, j + 1);
if (!M[d]) num[++cnt] = d, M[d] = cnt;
}
int T = gi<int>();
while (T--) solve();
return 0;
}
LL dfs(int x, int n, int m, int op) {
if (!x) return !num[n] || m % num[n] == 0;
if (!op && f[x][n][m] != -1) return f[x][n][m];
LL res = 0;
for (int i = 0; i <= (op ? a[x] : 9); i++)
res += dfs(x - 1, M[lcm(num[n], i)], (m * 10 + i) % 2520, op & i == a[x]);
if (!op) f[x][n][m] = res;
return res;
}