A - Beautiful numbers
Crawling in process... Crawling failed Time Limit:4000MS Memory Limit:262144KB 64bit IO Format:%I64d & %I64u
Submit Status Practice CodeForces 55D uDebug
Description
Input
Output
Sample Input
Sample Output
Hint
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
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 ·10^18).
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).
Input
1
1 9
Output
9
Input
1
12 15
Output
2
题意:问区间中有多少满足(这个数可以被它的每一位整除)的数的个数。
题解:
首先 0-9的lcm是2520。我们设为maxlcm。
数位DP无疑。我们设计状态,dp[I][j][k] i:当前位 J:前面的各个数位的lcm,k:前面数的大小%maxlcm,
这样数组得开到dp[25][2520][2520]. 这显然开不出来,我们考虑降低某一维的大小,通过考虑得出,前面各个数位的lcm并不是完全覆盖0-2520,所以采用离散化的方式,将这一维降成50。
代码:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#define ll long long
using namespace std;
const int maxlcm=2520;
int a[25];
ll dp[25][50][maxlcm+5];
ll gcd(ll x,ll y)
{
return y?gcd(y,x%y):x;
}
ll lcm(ll x,ll y)
{
return x/gcd(x,y)*y;
}
int Hash[maxlcm+5];
ll dfs(int pos,int plcm,int pmod,bool limit)
{
if(pos==-1)
return pmod%plcm==0;
if(!limit&&dp[pos][Hash[plcm]][pmod]!=-1)
return dp[pos][Hash[plcm]][pmod];
int up=limit?a[pos]:9;
ll ans=0;
for(int i=0; i<=up; i++)
{
int ppmod=(pmod*10+i)%maxlcm;
int pplcm=plcm;
if(i)
pplcm=lcm(plcm,i);
ans+=dfs(pos-1,pplcm,ppmod,limit&&i==a[pos]);
}
if(!limit)
dp[pos][Hash[plcm]][pmod]=ans;
return ans;
}
ll solve(ll x)
{
int pos=0;
while(x)
{
a[pos++]=x%10;
x/=10;
}
return dfs(pos-1,1,0,true);
}
void init()
{
int id=0;
memset(dp,-1,sizeof(dp));
for(int i=1; i<=maxlcm; i++)
{
if(maxlcm%i==0)
Hash[i]=id++;
}
}
int main()
{
int n;
ll l,r;
init();
cin>>n;
while(n--)
{
cin>>l>>r;
cout<<solve(r)-solve(l-1)<<endl;
}
return 0;
}