題名:
解決:
显然数位只有[1,9].
一些本题需要的数论知识:
1.如果x同时是a,b,c的倍数,那么x是lcm(a,b,c)的倍数.
2.[1,9]的lcm等于2520.
因此满足条件的数x,设x的数位lcm=mod,
那么x%mod=0一定成立,
令d[len][pre][mod]为:
1.数位剩余长度len,
2.数的和已经有pre,
3.当前数位lcm为mod,
的方案数.
第一维只有20,
第二维只需要存%2520的结果,因为膜数位lcm等于0的数,一定%2520=0.
第三维度其实只需要存50,因为[1,9]组合的不同lcm其实只有不到50种.
定义出状态,之后就是简单的数位dp了.
コード:
#include<bits/stdc++.h>
#define int long long
#define PI pair<int,int>
using namespace std;
const int maxm=2e6+5;
const int lc1=2520;
int d[20][2555][55];
int mp[2555],tot;
int digit[20];
void init(){
memset(d,-1,sizeof d);
for(int i=1;i<=lc1;i++){
if(lc1%i==0){
mp[i]=++tot;
}
}
}
int lcm(int a,int b){
return a/__gcd(a,b)*b;
}
int dfs(int len,int limit,int pre,int mod){
if(!len)return pre%mod==0;
if(!limit&&d[len][pre][mp[mod]]!=-1)return d[len][pre][mp[mod]];
int ans=0;
int ma=(limit?digit[len]:9);
for(int i=0;i<=ma;i++){
ans+=dfs(len-1,limit&&i==ma,(pre*10+i)%lc1,i==0?mod:lcm(mod,i));
}
if(!limit)d[len][pre][mp[mod]]=ans;
return ans;
}
int sol(int x){
int len=0;
while(x){
digit[++len]=x%10;
x/=10;
}
return dfs(len,1,0,1);
}
void solve(){
int l,r;cin>>l>>r;
int ans=sol(r)-sol(l-1);
cout<<ans<<endl;
}
signed main(){
ios::sync_with_stdio(0);
init();
int T;cin>>T;
while(T--){
solve();
}
return 0;
}