[Codeforces-div.1 55D] Beautiful numbers

[Codeforces-div.1 55D] Beautiful numbers

试题分析

还是离散化。。。\(f_{i,j,k}\)表示i位,gcd为j,余数为k。

#include<iostream>
#include<cstring>
#include<cstdio>
#include<vector>
#include<algorithm>
  
using namespace std;
#define LL long long
  
inline LL read(){
    LL x=0,f=1; char c=getchar();
    for(;!isdigit(c);c=getchar()) if(c=='-') f=-1;
    for(;isdigit(c);c=getchar()) x=x*10+c-'0';
    return x*f;
}
const LL MAXN = 100010;
const LL INF = 2147483600;
  
LL sta[MAXN+1]={0,1,2,3,4,5,6,7,8,9,10,12,14,15,18,20,21,24,28,30,35,36,40,42,45,56,60,63,70,72,84,90,105,120,126,140,168,180,210,252,280,315,360,420,504,630,840,1260,2520},top;
  
inline LL gcd(LL a,LL b){
    return (!b?a:gcd(b,a%b));
}
inline LL LCM(LL a,LL b){
    if(!a||!b) return b|a; 
    return a*b/gcd(a,b);
}
LL f[21][50][2600];
LL cnt; LL str[MAXN+1],num[MAXN+1];
 
inline LL dfs(LL i,LL j,LL k,LL g){
    if(i==0) return j&&(k%sta[j]==0);
    if(!g && ~f[i][j][k]) return f[i][j][k];
    LL ans=0; for(LL l=0;l<=(g?str[i]:9);l++){
        LL x=LCM(sta[j],l); 
        ans+=dfs(i-1,num[x],(k*10%2520+l)%2520,g&(str[i]==l));
    } return (g?ans:f[i][j][k]=ans);
}
inline LL init(LL x){
    cnt=0; while(x) str[++cnt]=x%10,x/=10;
    return dfs(cnt,0,0,1);
}
LL T;
  
int main(){
    //freopen(".in","r",stdin);
    memset(f,-1,sizeof(f));
    T=read(); for(LL i=1;i<49;i++) num[sta[i]]=i;
    while(T--){
        LL L=read(),R=read(); LL ans=0;
        ans+=init(R); ans-=init(L-1);
        printf("%lld\n",ans);
    }
    return 0;
}
posted @ 2018-08-23 10:14  wxjor  阅读(97)  评论(0编辑  收藏  举报