CF55D Beautiful(数位dp)

  暂时还没有完全领悟这道题的递推写法,先放代码

#include<iostream>
#include<algorithm>
#include<cstring>
#include<cstdio>
#include<map>
#include<string>
#include<vector>
using namespace std;
typedef long long ll;
const int N=2e5+5;
const int p=2520;
ll f[20][p+2][50];
int id[N];
int tot;
int val[N];
int mod(int a,int b){
    return (a%b+b)%b;
}
int gcd(int a,int b){
    return b?gcd(b,a%b):a;
}
int lcm(int a,int b){
    return a/gcd(a,b)*b;
}
void init(){
    int i,j,k,d;
    for(i=1;i<=p;i++)
    if(!(p%i))
        id[i]=++tot,val[tot]=i;
    for(i=1;i<=tot;i++)
    for(j=0;j<=p/val[i];j++)
    f[0][val[i]*j][i]=1;
    for(i=1;i<=19;i++)
    for(j=0;j<=p;j++)
    for(k=1;k<=tot;k++)
    for(d=0;d<=9;d++)
        f[i][j][k]+=f[i-1][(j*10+d)%p][id[d?lcm(val[k],d):val[k]]];
}
ll dp(ll x){
    int len=0; ll ans=0,Val=0,Lcm=1;
    int d[N];
    for(;x;x/=10) d[++len]=x%10;
    for(int i=len;i>=1;i--){
        for(int j=0;j<d[i];j++) ans+=f[i-1][(Val*10+j)%p][id[j?lcm(Lcm,j):Lcm]];
        Val=(Val*10+d[i])%p,Lcm=d[i]?lcm(Lcm,d[i]):Lcm;
    } return ans+!(Val%Lcm);

}
int main(){
    int t;
    cin>>t;
    init();
    while(t--){
        ll l,r;
        cin>>l>>r;
        cout<<dp(r)-dp(l-1)<<endl;
    }
    return 0;
}
View Code

 

posted @ 2020-04-12 22:58  朝暮不思  阅读(114)  评论(0编辑  收藏  举报