CF 55D 数位DP

原创 2016年06月07日 14:06:12

D. Beautiful numbers

time limit per test 4 seconds

memory limit per test 256 megabytes

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


题目大意:

一个整数如果能被它的所有非零数位整除,那么称这个数字为美丽数字。求给定区间内美丽数字的个数。

思路:

看一个结论(证明略):如果一个数是美丽数字,那么这个数必定能被它的所有非零数位的最小公倍数整除。相反,如果一个数能被它的所有非零数位的最小公倍数整除,那么这个数是美丽数字。

有了这个结论就可以进行数位dp了,记忆化搜索。已知1~9的lcm是2520。
dp[i][j][k]表示处理到第i位,这个数(包含第i位)对2520取余是j,所有位的lcm是k的数的个数。如果j对k取余等于0,则这些数是美丽数字。

k的范围是1~2520,这样会超内存,所以伴有离散化过程,所有情况的数位lcm也就48个。

#include <iostream>
#include <cstdio>
#include <string.h>
#include <algorithm>
#include <queue>
using namespace std;
const int mod=2520; //1~9的lcm为2520
int gcd(int a,int b) {
    if(b==0) return a;
    return gcd(b,a%b);
}
int lcm(int a,int b) {
    if(a==0) return b;
    if(b==0) return a;
    return a*b/gcd(a,b);
}
int index[2525];
int initIndex() {
    int tmp = 0;
    for(int i=1;i<=2520;i++)
        if(2520%i==0) index[i] = tmp++;
}
long long dp[25][mod][50];
int bit[25];
long long dfs(int pos,int prenum,int prelcm,bool flag) { //flag为true的话表示当前位触顶了
    if(pos==-1) return prenum%prelcm == 0;
    if(!flag && dp[pos][prenum][index[prelcm]]!=-1) return dp[pos][prenum][index[prelcm]];
    int e = flag?bit[pos]:9;
    long long ans=0;
    for(int i=0;i<=e;i++) {
        ans += dfs(pos-1,(prenum*10+i)%mod,lcm(prelcm,i),flag&&i==e);
    }
    if(!flag) return dp[pos][prenum][index[prelcm]]=ans;
    return ans;
}

long long solve(long long n) {
    int pos=0;
    while(n) {
        bit[pos++] = n%10;
        n/=10;
    }
    return dfs(pos-1,0,1,true);
}
int main() {
    int T;
    long long l,r;
    initIndex();
    memset(dp,-1,sizeof(dp));
    cin>>T;
    while(T--) {
        cin>>l>>r;
        cout<<solve(r)-solve(l-1)<<endl;
    }
}
版权声明:本文为博主原创文章,未经博主允许不得转载。

相关文章推荐

CF 55D Beautiful numbers (数位DP)

题意:给定一个[l, r]区间,求其中该数能被其自身每一位数整除的数的个数。 思路: 显然是数位DP。能整除其自身每一位,即能整除其自身每一位数的最小公倍数。lcm(2,...,9)== 2520。对...

CF 55D(数位DP)

嗯,写完这个题后对数位dp有了一个更清楚的认识 关键是对状态的一些理解 题意就是对l到r区间内,能被他的非零位数整除的数的个数 那么对于每一个第k位,前面数字之和是i,前面位数的最小公倍数是j的...
  • cbcbcbz
  • cbcbcbz
  • 2017年07月14日 10:57
  • 48

CF - 55D 数位dp + 状压

题意: 求出区间[l,r]中的所有Beautiful Number的数目,如果一个数x可以被它各个数位上的非零数整除,那它就是Beautiful Number。 思路: 很巧妙的一道数位dp,没...
  • Bahuia
  • Bahuia
  • 2017年01月08日 22:57
  • 135

CF55D Beautiful numbers (数位DP)

codeforces 55D Beautiful numbers (数位DP) 原题地址:http://codeforces.com/problemset/problem/55/D ...

【数位DP】CF55D BZOJ3329 HDU4352 SGU390 HDU5519

前言有一些题之前已经写了题解了,就只留一个链接吧…一般的数位DP都是计算一段区间满足某条件的数有多少个。 顾名思义数位DP就是按照数一位一位滴进行DP。通常至少有二维,其中一位表示当前在第ii位上,...
  • cqbztsy
  • cqbztsy
  • 2016年02月27日 01:12
  • 685

CF 55D Beautiful numbers (数位DP入门)

题意是:求 [l,r] 区间内完美数的个数,完美数的定义:这个数能是所有位数的倍数,比如42,42是4的倍数,也是2的倍数。 考虑数位DP, LL dfs(int pos,int now,int ...

CF-55D-数位DP-Beautiful Number

题意 求给定区间内 beautiful number 的数目 beautiful number :能被它自身非零位整除 思路 一个数字要被它的所有非零位整除,即被他们的LCM整除 若 ...
  • sinluan
  • sinluan
  • 2015年11月09日 14:07
  • 188

【动态规划】【数位DP】[Codeforces 55 D]Beautiful numbers

题目描述Volodya is an odd boy and his taste is strange as well. It seems to him that a positive integer ...

codeforces-55D-Beautiful numbers(数位DP)

 A - Beautiful numbers Time Limit:4000MS     Memory Limit:262144KB     64bit IO Format:%...

数位dp专题 (HDU 4352 3652 3709 4507 CodeForces 55D POJ 3252)

数位dp核心在于状态描述,因为阶段很简单。 一般都是求有多少个数,当然也有求平方的变态题。 因为比这个数小的范围定然是从左至右开始小的,那么什么样的前缀对后面子数有相同的结果? HDU 3652...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:CF 55D 数位DP
举报原因:
原因补充:

(最多只允许输入30个字)