数位DP求调
查看原帖
数位DP求调
490978
小超手123楼主2023/6/8 14:50
#include<bits/stdc++.h>
#define int long long
using namespace std;
int T;
int P[2530], Q[50], tot;
int f[20][2530][50][2]; 
//f[i][j][k][l] 表示前 i 位,当前数 % 2520 = j , 最大公倍数 = k , l:卡没卡住 
int A[20], num;
int gcd(int x, int y) {
    if(y == 0) return x;
    return gcd(y, x % y);
}
int lcm(int x, int y) {
    return x * y / gcd(x, y);
}
int dfs(int Pos, int now, int S, int lim) {
    if(Pos == num + 1) {
    	if(now % Q[S] == 0) return 1;
    	else return 0;
    }
    if(f[Pos][now][S][lim] != -1) return f[Pos][now][S][lim];
    int ans = 0;
    for(int i = 0; i <= (lim == 1 ? A[Pos] : 9); i++) 
        ans += dfs(Pos + 1, (now * 10 + i) % 2520, P[i == 0 ? Q[S] : lcm(Q[S], i)], (i == A[Pos]) && lim);
	return f[Pos][now][S][lim] = ans;
}
int Sol(int x) {
    num = 0;
    memset(f, -1, sizeof(f));
    while(x) {
        A[++num] = x % 10;
        x /= 10;
	}
	reverse(A + 1, A + num + 1);
	return dfs(1, 0, 0, 1);
}
signed main() {
	Q[0] = 1;
	for(int i = 1; i <= 2520; i++) 
		if(2520 % i == 0) P[i] = ++tot, Q[tot] = i;
//	cout << tot << endl;
    cin >> T; 
    while(T--) {
        int l, r;
        cin >> l >> r;
        cout << Sol(r) - Sol(l - 1) << endl;
	}
    return 0;
}

2023/6/8 14:50
加载中...