Codeforces 55D Beautiful Number

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Codeforces 55D Beautiful Number相关的知识,希望对你有一定的参考价值。

Codeforces 55D Beautiful Number

a positive integer number is beautiful if and only if it is divisible by each of its nonzero digits.

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).

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).

Sample test(s)
Input
1
1 9
Output
9
Input
1
12 15
Output
2

思路:

  1. 在mod中,有一个规律,X%a = X%(b*a)%a; <=> X%( lcm(1,2,...,9) = 2520)%lcm(d[i]) == 0;即可将数值直接降到2520以内;
  2. 同时一个mod后的数,还需要记录的就是lcm(d[i]),这样每次又计算出来的子结构就直接相加即可(指mod之后的数值以及lcm相同的数(这时就可以看成是一个数)),lcm总共只有48个,(2^3,3^2,5,7的组合 4*3*2*2);
  3. dp[i][j][k]: [i]: 高位为第i位,[j] : 在mod 2520之后的数值,[k]:记录下高位的lcm,由于直接来会MLE,所以离散化了(使用标号index[]);

代码思路参考了:AC_Von

技术分享
#include<bits/stdc++.h>
using namespace std;
#define rep(i,n) for(int (i)= 0;i < (n);i++)
#define MS0(a) memset(a,0,sizeof(a))
#define MS1(a) memset(a,-1,sizeof(a))
typedef long long ll;
const int MOD = 2520;
ll dp[21][2520][50];
int d[21],index[MOD+5];
void init()
{
    for(int i = 1,tot = 0;i <= MOD;i++)
        if(MOD % i == 0)  index[i] = tot++;
    MS1(dp);
}
int lcm(int a,int b)
{
    return a/__gcd(a,b)*b;
}
ll dfs(int pos,int prev,int prelcm,int edge)
{
    if(pos == -1) return prev % prelcm?0:1; // ***
    ll ans = dp[pos][prev][index[prelcm]];
    if( !edge && ~ans) return ans;
    ans = 0;
    int e = edge ? d[pos]:9;
    for(int i = 0;i <= e;i++){
        int nowlcm = i ? lcm(prelcm,i) : prelcm;
        int nowv = (prev * 10 + i)%MOD;
        ans += dfs(pos - 1,nowv,nowlcm,edge && i == e);
    }
    if(!edge) dp[pos][prev][index[prelcm]] = ans;
    return ans;
}
ll query(ll n)
{
    MS0(d);int tot = 0;
    while(n){
        d[tot++] = n%10;
        n /= 10;
    }
    return dfs(tot - 1,0,1,1);
}
int main()
{
    init();
    int T;
    cin>>T;
    while(T--){
        ll l,r;
        scanf("%I64d%I64d",&l,&r);
        printf("%I64d\\n",query(r) - query(l-1));
    }
}
View Code

 

以上是关于Codeforces 55D Beautiful Number的主要内容,如果未能解决你的问题,请参考以下文章

CodeForces - 55D Beautiful numbers (数位DP)

CodeForces 55D Beautiful numbers

CodeForces 55D - Beautiful numbers - [数位DP+离散化]

codeforces55D Beautiful numbers

CodeForces - 55D - Beautiful numbers(数位DP,离散化)

CodeForces 55D Beautiful numbers