标签:codeforces dp 数论
求在[l,r]中能够整除自己每个数位上的数字的数的个数。
#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
using namespace std;
typedef long long LL;
LL dp[20][50][3000];
int d[20],hash[3000];
const int mod = 2520;
int gcd ( int a ,int b )
{
return !b?a:gcd(b,a%b);
}
void init ( )
{
memset ( dp , -1 , sizeof ( dp ) );
int cc = 0;
for ( int i = 1 ; i <= 8 ; i *= 2 )
for ( int j = 1; j <= 9 ; j*= 3 )
for ( int k = 1 ; k <= 5 ; k *= 5 )
for ( int t = 1; t <= 7 ; t *= 7 )
hash[i*j*k*t] = ++cc;
}
LL dfs ( int n , int lcm , int f , int r )
{
if ( !n ) return r%lcm==0;
int ll = hash[lcm];
if ( f && dp[n][ll][r] != -1 )
return dp[n][ll][r];
int x = f?9:d[n];
LL ret = 0;
for ( int i = 0 ; i <= x ;i++ )
ret += dfs ( n-1 , i==0?lcm:lcm*i/gcd(lcm,i) , i==x?f:1 , (r*10+i)%mod );
return f? dp[n][ll][r] = ret : ret;
}
LL solve ( LL x )
{
int cc = 0;
while ( x )
{
d[++cc] = x%10;
x /= 10;
}
return dfs ( cc , 1 , 0 , 0 );
}
int main ( )
{
int t;
LL a,b;
scanf ( "%d" , &t );
init ( );
while ( t-- )
{
scanf ( "%lld%lld" , &a , &b );
printf ( "%lld\n" , solve ( b ) - solve ( a-1 ) );
}
}
版权声明:本文为博主原创文章,未经博主允许不得转载。
codeforces 55D D. Beautiful numbers(数位dp+数论)
标签:codeforces dp 数论
原文地址:http://blog.csdn.net/qq_24451605/article/details/48274605