题目链接:http://codeforces.com/problemset/problem/55/D
题目大意:Beautiful numbers定义:能被自身所有非零数位整除的数。就比如15是Beautiful numbers,因为15可以被1,5整除,14不是,因为14不能被4整除。

问:L到R区间内有多少个Beautiful numbers
思路:
这个题就是整除比较难处理。

1: int MOD = LCM{1,2,9} = 5 * 7 * 8 * 9 = 2520
2: 按照定义,数字x为Beautiful : x % LCM{digit[xi]} = 0 即 x % MOD % LCM{digit[xi]} = 0,所以可以只需存x % MOD,范围缩小了。

那么统计已经出现的LCM{}和MOD就行了。
由2可以推出结论:n%a = (n%k * a)%a (k!=0)
a = LCM {}, 因为所有的LCM{}都是2520的因数。所以:2520=k * LCM{}。

我们要确定:n%LCM{}==0, 只要确定(n%2520)%LCM{}==0就可以了。

那么状态就很好表示了,只有保存n%2520就可以了。

这个前面不要13的倍数那道题用过。

当然LCM{}可以离散化一下,只有48个。

dp[20][3000][50]就可以保存所有的状态了。

#include <bits/stdc++.h>
#define LL long long
using namespace std;
const int mod=2520;

int a[20];
int index[3000];//1...9的各种lcm可以离散化处理,只有48个
LL dp[20][3000][50];
void LCMCSL()
{
    int cut=0;
    for(int i=1;i<=mod;i++)
    {
        if(mod%i==0)
        {
            index[i]=cut++;
        }
    }
}

LL LCM(LL a, LL b)
{
    if(a==0)
    {
        return b;
    }
    return a/__gcd(a, b)*b;
}

LL dfs(int pos, int mod, int Lcm, int mt)
{
    if(pos==-1)
    {
        return mod%Lcm==0;
    }

    if(!mt&&dp[pos][mod][index[Lcm]]!=-1)
    {
        return dp[pos][mod][index[Lcm]];
    }

    int Len=mt?a[pos]:9;
    LL ans=0;
    for(int i=0;i<=Len;i++)
    {
        ans+=dfs(pos-1, (mod*10+i)%2520, LCM(i, Lcm), i==a[pos]&&mt);
    }

    if(!mt)
    {
        dp[pos][mod][index[Lcm]]=ans;
    }

    return ans;

}

LL slove(LL x)
{
    int pos=0;
    while(x)
    {
        a[pos++]=x%10;
        x/=10;
    }

    return dfs(pos-1, 0, 1, 1);
}

int main()
{
    LCMCSL();
    int T;
    memset(dp, -1, sizeof(dp));
    scanf("%d",&T);
    while(T--)
    {
        LL L, R;
        scanf("%lld%lld",&L,&R);

        printf("%lld\n", slove(R)-slove(L-1));
    }

    return 0;
}