cf Beautiful numbers(数位dp)

Beautiful numbers

Time Limit:4000MS     Memory Limit:262144KB     64bit IO Format:%I64d
& %I64u

Submit Status Practice CodeForces
55D

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?·1018).

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

Sample Input

Input

1
1 9

Output

9

Input

1
12 15

Output

2

题意:求区间内能整除自己每位数(0除外)的个数。

code:

#include<cstdio>
#include<algorithm>
#include<cstring>
#include<iostream>
#include<cmath>
#define ll long long
#define Mod 2520  ////1-9的最小公倍数

using namespace std;

ll l,r;
ll dp[30][Mod][50];///dp[i][j][k] i:长度  j:各个位数最小公倍数对Mod取摸  k:最小公倍数对应的值得离散下标
int num[30];
int b[Mod+1];     ///记录最小公倍数

ll gcd(ll a,ll b) {
    return b==0?a:gcd(b,a%b);
}

ll Lcm(ll a,ll b) {
    return a/gcd(a,b)*b;
}

ll dfs(int i,ll lcm,ll sum,bool e) {
    if(i<=0)return sum%lcm==0;
    if(!e&&dp[i][sum][b[lcm]]!=-1)return dp[i][sum][b[lcm]];
    ll res=0;
    int u=e?num[i]:9;
    for(ll d=0; d<=u; d++) {
        if(d==0)                 ///d==0时,lcm不变
            res+=dfs(i-1,lcm,sum*10%Mod,e&&d==u);
        else
            res+=dfs(i-1,lcm*d/gcd(lcm,d),(sum*10+d)%Mod,e&&d==u);
    }
    return e?res:dp[i][sum][b[lcm]]=res;
}

ll solve(ll n) {
    int len=1;
    while(n) {
        num[len++]=n%10;
        n/=10;
    }
    return dfs(len-1,1,0,1);
}

int main() {
    memset(dp,-1,sizeof dp);
    int cnt=0;
    ///离散记录lcm值
    for(int i=1; i<=Mod; i++)if(Mod%i==0)b[i]=cnt++;
    int t;
    scanf("%d",&t);
    while(t--) {
        scanf("%I64d%I64d",&l,&r);
        ll ans=solve(r)-solve(l-1);
        printf("%I64d\n",ans);
    }
    return 0;
}
时间: 2024-10-09 01:00:25

cf Beautiful numbers(数位dp)的相关文章

CodeForces 55D Beautiful numbers 数位DP+数学

题意大概是,判断一个正整数区间内有多少个整数能被它自身的每一个非零的数字整除. 因为每一个位置上的整数集s = {0,1,2,3,4,5,6,7,8,9} lcm(s) = 2520 现在有一个整数t是由s中一个或者多个数字构成的,记为abcde,显然t = a*10^4+b*10^3+c*10^2+d*10^1+e 要使得t能被a,b,c,d,e整除,必然有t % lcm(a,b,c,d,e) = 0 因为a,b,c,d,e去重之后一定是s的一个子集,所以lcm(s)一定是lcm(a,b,c,

Codeforces Beta Round #51---D. Beautiful numbers(数位dp, 巧妙)

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 num

CodeForces 55D Beautiful numbers(数位dp&amp;&amp;离散化)

题目链接:[kuangbin带你飞]专题十五 数位DP A - Beautiful numbers 题意 ps:第一道数位dp,题真好,虽然是参考大牛方法悟过才a,但仍收获不少. 求一个区间内的Beautiful numbers有多少个.Beautiful numbers指:一个数能整除所有组成它的非0数字. 例如15可以被1和5整除,所以15是Beautiful numbers. 思路 Beautiful numbers指:一个数能整除所有组成它的非0数字. 等同于 一个数能整除 所有组成它的

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

题目链接:https://cn.vjudge.net/problem/CodeForces-55D 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

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

链接: https://vjudge.net/problem/CodeForces-55D 题意: 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

CF55D Beautiful numbers (数位dp)

题目链接 题解 一个数能被一些数整除,那么一定被这些数的\(lcm\)整除 那么我们容易想到根据\(lcm\)设状态 我们可以发现有用的\(lcm\)只有\(48\)个 那么按照一般的数位\(dp\) 设出状态:\(f_{i,j,k,0/1}\)表示前\(i\)位,\(lcm=j\),模\(lcm\)的余数是\(k\),是否达到上界 但是这样子是无法转移的(因为新添加一个数模数可能会产生变化) 那么我们把模数统一成\(2520\) 复杂度\(O(T*L*48*2500*2)\) 其中\(L\)是

codeforces 55D D. Beautiful numbers(数位dp+数论)

题目链接: codeforces 55D 题目大意: 求在[l,r]中能够整除自己每个数位上的数字的数的个数. 题目分析: 首先我们能够知道如果这个数能够整除它的每个数位上的数字,那么它一定能够整除他们的最小公倍数,是充要的. 那么我们定义状态dp[i][j][k]代表i位在任意组合下得到的所有数位的数字的最小公倍数为j的每个数位上的数字之积%2520为k的方案数. 我们可以知道所有的公倍数最大不会超过2520,而且他们都是2520的约数,所以如果他们能够整除2520的余数,那么证明他们能够整除

CodeForces 55D Beautiful numbers (数位DP)

题意:给求给定区间中该数能整除每一位的数的数量. 析:dp[i][j][k] 表示前 i 位,取模2520为 j,最小倍数是 k,但是这样,数组开不下啊,那怎么办呢,其实,0-9的最小公倍数的不同各类并没有那么多, 其实就48种,所以我们可以给这48个一个编号,然后就能开出来了. 代码如下: #pragma comment(linker, "/STACK:1024000000,1024000000") #include <cstdio> #include <strin

Codeforces 55D Beautiful numbers 数位dp(入门

题目链接:点击打开链接 题意: 我们认为一个数 num 能被每一位上的数字整除(expect 0) 那么这个数num就是合法的. 给出区间[l,r] ,问这个区间内有多少个合法的数. 首先solve(long x) 返回 [0, x] 内的合法个数,答案就是 solve(r) - solve(l-1); 以1234567为例 flag表示当前这位是能任意填,还是只能填<=该位对应的数字 若当前搜索的是第三位,且第二位已经填了0或1,则此时第三位可以任意填. 若第二位填的是2,则第三位只能填 [0

CF55D Beautiful numbers 数位dp

恢复魔芋本质,,改了1h+,, 题目传送门 其实这个题挺水的.也就我这种忘了%大佬的蒟蒻要调这么久. 首先,我们要找的是能被每一位整除的数.处理成1~R的答案  -  1~(l-1)的答案. 从最高位开始搜索放啥.如果已经是最后一位了,且当前数能被当前各位的最小公倍数整除,它就是一个合法的方案.那么,将长度,当前和,当前lcs,是否有限制带着搜就行了. 注意,因为每一位只有1~9,这里的不同lcs最多不到50个,预处理离散化一下即可. 还有就是本组数据结束的时候要把有限制的清空,无限制的保留(最