您的位置:首页 > 其它

CodeForces 55D Beautiful numbers (数位DP)

2016-09-19 20:45 417 查看


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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: