【Hoj1983】美丽数Beautiful numbers
Description
在他看来,一个正整数是美丽的,当且仅当它可以被它的每个非零数字整除。
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
Multiple test cases.
Each line contains two natural numbers li and ri (1 ≤ li ≤ ri ≤ 9 · 10^18).
Output
One line specifies the answer.
Sample Input
1 9
12 15
Sample Output
9
2
思路
- 2520是1~9的最小公倍数,2520共有几十个约数
- 注意long long
- hash
代码
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
int bit[22],hash[2525],cnt;
long long dp[22][2525][50],a,b;
long long gcd(long long a,long long b){return !b?a:gcd(b,a%b);}//最大公因数
long long lcm(long long a,long long b){return a/gcd(a,b)*b;}//最小公倍数
long long dfs(int x,int num,int mod,int flag)
{
if(x==1) return num%mod==0;
if(!flag&&dp[x][num][hash[mod]]!=-1) return dp[x][num][hash[mod]];
int count=flag?bit[x-1]:9; long long ans=0;
for(int i=0;i<=count;++i) ans+=dfs(x-1,(num*10+i)%2520,i?lcm(mod,i):mod,flag&&i==count);
return flag?ans:dp[x][num][hash[mod]]=ans;
}
long long start(long long x)
{
int len=0;
for(;x;x/=10) bit[++len]=x%10;
return dfs(len+1,0,1,1);
}
signed main()
{
memset(dp,-1,sizeof(dp));
for(int i=1;i*i<=2520;++i)
if(2520%i==0) hash[i]=++cnt,hash[2520/i]=++cnt;
while(~scanf("%lld%lld",&a,&b)) printf("%lld\n",start(b)-start(a-1));
return 0;
}