您的位置:首页 > 其它

Beautiful numbers CodeForces - 55D 数位dp

2017-05-15 21:39 260 查看
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).

Examples

input
1
1 9


output
9


input
1
12 15


output
2


题意:数位统计,l,r内满足条件的数的个数

条件:这个数的值可以被这个数所有的数位整除

之前做过数位统计,这个数可以被某一个数整除的题,大约就是记录余数作为状态,这个当然也想到了记录余数,但是每次记录对谁的余数是个问题,

想到了数位上能出现的数字只能是0~9,因此求一个lcm(1,2,3....9)=2520,记录对他的余数即可,然后在记录一个前面已经出现的数位的最小公倍数,

但是很傻,没想到会出现的最小倍数并不多,可以离散化。。。。就没弄出来,看了题解恍然大悟。。。。

还有就是这个题应该还是要记一下前导零的,因为按这种统计方法,前面是“0000”的状态和“1111”的状态是重复的 ,都是余数为0,最小公倍数为1

#include<iostream>
#include<algorithm>
#include<stdio.h>
#include<map>
#include<vector>
#include<string.h>
using namespace std;
long long dp[20][3000][50],a[200];
int lisan[3000];
const long long mo=2520;
long long gcd(long long x,long long y)
{
return y==0?x:gcd(y,x%y);
}
long long lcm(long long x,long long y)
{
return x*y/gcd(x,y);
}
long long dfs(int pos,int limit,long long yu,long long lcmm,long long tt,int lead)
{
if(pos==-1)
{
return yu%lcmm==0&&!lead;
}
int index=lisan[lcmm];
if(dp[pos][yu][index]!=-1&&!limit&&!lead)
return dp[pos][yu][index];
int up=limit?a[pos]:9;
long long ans=0;
for(int i=0;i<=up;i++)
{
if(i==0)
ans+=dfs(pos-1,limit&&i==a[pos],(yu+tt*i)%mo,lcmm,tt/10,lead&&i==0);
else
ans+=dfs(pos-1,limit&&i==a[pos],(yu+tt*i)%mo,lcm(lcmm,i),tt/10,lead&&i==0);
}
if(dp[pos][yu][index]==-1&&!limit&&!lead)
dp[pos][yu][index]=ans;
return ans;
}
long long solve(long long x)
{
int pos=0;
long long tt=1;
while(x)
{
a[pos++]=x%10;
x/=10;
if(x)
tt*=10;
}
return dfs(pos-1,1,0,1,tt,1);
}
int main()
{
long long l,r;
int T;
int now=0,i,j;
for(i=1;i<=mo;i++)
{
if(mo%i==0)
lisan[i]=now++;
}
cin>>T;
memset(dp,-1,sizeof(dp));
while(T--)
{
scanf("%lld %lld",&l,&r);
printf("%lld\n",solve(r)-solve(l-1));
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: