codeforces 55D Beautiful numbers[数位dp]

来源:互联网 发布:java如何转换日期格式 编辑:程序博客网 时间:2024/04/30 09:50
D. Beautiful numbers
time limit per test
4 seconds
memory limit per test
256 megabytes
input
standard input
output
standard output

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).

Sample test(s)
input
11 9
output
9
input
112 15
output
2

Analyse:

一个数能被自己的所有非0位整除,题目要求区间【l,r】中这样的数的个数;


即求,一个数能被自己所有的数的lcm整除。 x%lcm(∑ xi)==0;

因为1-9的最小公倍数为2520,so

--->  x%2520%lcm(∑ xi)==0;

     ((x1*10+x2)*10+x3)*10+x4).......%2520

==((x1*10+x2)%2520*10+x3)%2520*10+x4)%2520.......%2520

于是数位dp,记忆化dp[pos][prelcm][premod];  18*2520*2520...MLE..prelcm其实只有几十个,见代码cnt的值,,(好像为cnt=48个)


Code:

#include<iostream>#include<cstdio>#include<cstring>#include<cmath>#include<algorithm>#include<vector>#include<string>#include<queue>#include<deque>#include<stack>#include<map>#include<set>#define INF 0x7fffffff#define SUP 0x80000000#define mem(a,b) memset(a,b,sizeof(a))using namespace std;typedef long long LL;const int N=100007;LL l,r;LL dp[20][50][2520];int mapp[2521];int len,digit[20];int gcd(int a,int b){    return b==0?a:gcd(b,a%b);}int lcm(int a,int b){    return a/gcd(a,b)*b;}LL dfs(int pos,int prelcm,int premod,int limit){    if(pos==-1) return (premod%prelcm==0);    if(!limit&&dp[pos][mapp[prelcm]][premod]!=-1) return dp[pos][mapp[prelcm]][premod];    int last=limit?digit[pos]:9;    LL ret=0;    for(int i=0;i<=last;i++)    {        if(i==0)            ret+=dfs(pos-1,prelcm,(premod*10+i)%2520,limit&&(i==last));        else            ret+=dfs(pos-1,lcm(prelcm,i),(premod*10%2520+i)%2520,limit&&(i==last));    }    if(!limit) dp[pos][mapp[prelcm]][premod]=ret;    return ret;}LL solve(LL x){    len=0;    while(x)    {        digit[len++]=x%10;        x/=10;    }    LL ret=dfs(len-1,1,0,1);    //cout<<ret<<endl;    return ret;}int main(){    int cnt=0;    for(int i=1;i<=2520;i++)    {        if(2520%i==0)            mapp[i]=cnt++;    }    mem(dp,-1);    int T;    scanf("%d",&T);    while(T--)    {        scanf("%I64d%I64d",&l,&r);        printf("%I64d\n",solve(r)-solve(l-1));    }    return 0;}





0 0