codeforces 55D Beautiful numbers

Posted on 2016-12-22 14:29  ziliuziliu  阅读(111)  评论(0)    收藏  举报

具体的dp不用说。

注意有个问题:有很多状态是0,但其实是访问到了的。所以一开始要memset为-1才不会T那个最大的点。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define maxn 3050
using namespace std;
int t,a[maxn],hash[maxn],tot=0,bit[30],times=0,ret=0;
long long l,r,dp[20][maxn][50];
int gcd(int a,int b)
{
    if (!b) return a;
    return gcd(b,a%b);
}
void get_table()
{
    for (int i=1;i<=2520;i++) if (2520%i==0) a[++tot]=i;
    for (int i=1;i<=tot;i++) hash[a[i]]=i;
}
void ask_bit(long long x)
{
    ret=0;    
    while (x) 
    {
        bit[++ret]=(int)(x%10);
        x/=10;
    }
}
long long dps(int pos,int mod,int l,bool flag)
{
    if (!pos) return mod%l==0;
    long long &f=dp[pos][mod][hash[l]];
    if (flag && f!=-1) return f;
    int lim=flag?9:bit[pos];long long ans=0;
    for (int i=0;i<=lim;i++)
        ans+=dps(pos-1,(mod*10+i)%2520,i?l*i/gcd(l,i):l,flag|(i<lim));
    return flag?f=ans:ans;
}
long long work(long long x) {ask_bit(x);return dps(ret,0,1,0);}
int main()
{
    scanf("%d",&t);get_table();memset(dp,-1,sizeof(dp));
    for (int i=1;i<=t;i++)
    {
        scanf("%lld%lld",&l,&r);
        printf("%lld\n",work(r)-work(l-1));
    }
    return 0;
}