Beautiful numbers (CodeForces - 55D)数位DP

Volodya is an odd boy and his taste is strange as well. It seems to him that a positive integer number is beautiful if and only if it is divisible by each of its nonzero digits. We will not argue with this and just count the quantity of beautiful numbers in given ranges.

Input

The first line of the input contains the number of cases t (1 ≤ t ≤ 10). Each of the next t lines contains two natural numbers li and ri (1 ≤ li ≤ ri ≤ 9 ·1018).

Please, do not use %lld specificator to read or write 64-bit integers in C++. It is preffered to use cin (also you may use %I64d).

Output

Output should contain t numbers — answers to the queries, one number per line — quantities of beautiful numbers in given intervals (from li to ri, inclusively).

Examples

Input

1
1 9

Output

9

Input

1
12 15

Output

2

题意:这道题的话,就是让你找到在给定区间里的漂亮数字。那么什么是漂亮数字呢。就是当一个数可以被它的每一位非零位数整除,我们就叫它漂亮数字。

思路:因为这道题是让你求出漂亮数字,而且漂亮数字的定义也告诉你了。所以我们根据漂亮数字的定义可以推出,既然它可以被每一位非零位数整除,那么就可以被1~9的最小公倍数整除,而1~9的最小公倍数是2520。所以思路就很明显了。

那么我们设dfs(pos,num,state,limit)分别表示了第几位,当前数字,当前数字所有非零位的最小公倍数,是否有限制。当前数字因为太大,而我们最终枚举完后只需要判断num%state是否为0,所以每次传入的num每次模2520即可,这样就可以小很多,所以我们的dp数组可以开三维dp[pos][num][state],分别是第几位,数字取模后的大小,最小公倍数,这样我们至少要开19x2520x2520的大小,肯定开不了,所以对于state这一维我们需要进行离散化,经过打表可以发现,2520内可以整除2520的只有48个,所以我们可以离散化一下让state映射到1-48既可以了这样就可以开19x2520x48大小的了。


AC代码:

#include <bits/stdc++.h>
typedef long long ll;
const int maxx=3010;
const int inf=0x3f3f3f3f;
const int mod=2520;
using namespace std;
ll a[100];
ll Hash[maxx];
ll dp[100][maxx][100];
void init()
{
    int cnt=0;
    for(int i=1;i<=mod;i++)
    {
        if(mod%i==0)
            Hash[i]=cnt++;
    }
}
ll gcd(ll a,ll b)
{
    if(!b)
        return a;
    else
        return gcd(b,a%b);
}
ll dfs(int pos,int num,int state,bool limit)
{
    if(pos==-1)
        return num%state==0;
    if(!limit && dp[pos][num][Hash[state]]!=-1)
       return dp[pos][num][Hash[state]];
    int up=limit?a[pos]:9;
    ll ans=0;
    for(int i=0;i<=up;i++)
    {
        ans+=dfs(pos-1,(num*10+i)%mod,(!i?state:state*i/gcd(state,i)),limit && i==a[pos]);
    }
    if(!limit)
        dp[pos][num][Hash[state]]=ans;
    return ans;
}
ll solve(ll x)
{
    int pos=0;
    while(x)
    {
        a[pos++]=x%10;
        x/=10;
    }
    return dfs(pos-1,0,1,true);
}
int main()
{
    init();
    int t;
    scanf("%d",&t);
    memset(dp,-1,sizeof(dp));
    while(t--)
    {
        ll l,r;
        scanf("%lld%lld",&l,&r);
        printf("%lld\n",solve(r)-solve(l-1));
    }
    return 0;
}
发布了204 篇原创文章 · 获赞 16 · 访问量 2万+

猜你喜欢

转载自blog.csdn.net/weixin_43846139/article/details/103902445